PHP SimpleXML
SimpleXML è un'estensione PHP che fornisce un'API semplice per lavorare con documenti XML, consentendo di analizzare e manipolare facilmente i dati.
Introduzione
SimpleXML è un'estensione PHP integrata che trasforma un documento XML in un oggetto navigabile con la normale sintassi di proprietà e array. Invece di scorrere manualmente un albero di nodi, si scrive $xml->book->title — i nomi degli elementi diventano proprietà e gli elementi ripetuti diventano elenchi iterabili.
Questo rende SimpleXML il modo più rapido per leggere un file di configurazione, elaborare la risposta di un'API XML o generare un piccolo documento XML. Questa pagina illustra il caricamento di XML, la lettura di elementi e attributi, la gestione dei namespace, le query con XPath, la modifica dei documenti e la gestione degli errori di analisi.
SimpleXML è la scelta ideale per documenti che si adattano comodamente alla memoria e hanno una struttura nota e abbastanza piatta. Per file molto grandi o per un controllo granulare a basso livello, si può preferire PHP XML DOM o il parser XML basato su Expat.
Caricamento di un documento XML
Si costruisce un SimpleXMLElement a partire da una delle tre fonti:
simplexml_load_string()— analizza XML contenuto in una stringa (utile per le risposte API).simplexml_load_file()— analizza XML memorizzato in un file o URL.new SimpleXMLElement($xml)— il costruttore, che accetta una stringa per impostazione predefinita.
Tutte e tre restituiscono un SimpleXMLElement che rappresenta l'elemento radice del documento — non un wrapper attorno all'intero file. Quindi se la radice è <library>, l'oggetto restituito è <library>.
<?php
$data = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book category="fiction">
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
<price>14.99</price>
</book>
<book category="science">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<price>18.50</price>
</book>
</library>
XML;
$library = simplexml_load_string($data);
echo get_class($library); // SimpleXMLElementLettura di elementi e attributi
Gli elementi figlio sono accessibili come proprietà. Quando un elemento si ripete (come <book>), la proprietà si comporta come un elenco indicizzabile con [] o iterabile con foreach. Gli attributi si leggono con accesso in stile array ($element['attr']).
<?php
$library = simplexml_load_string($data); // the XML from above
echo $library->book[0]->title . "\n"; // The Hobbit
echo count($library->book) . "\n"; // 2
foreach ($library->book as $book) {
echo $book->title . " — " . $book['category'] . "\n";
}Output:
The Hobbit
2
The Hobbit — fiction
A Brief History of Time — scienceAttenzione: un elemento a cui si accede in questo modo è un
SimpleXMLElement, non una stringa.$book->priceviene stampato come testo grazie al suo metodo__toString(), ma per operazioni aritmetiche o confronti rigorosi è necessario effettuare un cast:(float) $book->priceoppure(string) $book['category']. Dimenticarsi del cast è il bug più comune con SimpleXML.
Query con XPath
Per qualsiasi operazione che vada oltre la semplice navigazione — filtraggio, ricerca in profondità nell'albero, selezione condizionale — usare xpath(). Esegue un'espressione XPath e restituisce un array di elementi corrispondenti.
<?php
$library = simplexml_load_string($data);
// Titles of books priced over 10
foreach ($library->xpath('//book[price>10]/title') as $title) {
echo $title . "\n";
}
// The Hobbit
// A Brief History of TimeLavorare con i namespace
Quando un documento utilizza namespace XML, non è possibile accedere agli elementi con prefisso tramite la normale proprietà — è necessario chiamare children() (per gli elementi) o attributes() (per gli attributi) con l'URI del namespace, oppure registrare il prefisso prima di eseguire XPath.
<?php
$rss = <<<XML
<rss xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<item>
<title>Hello</title>
<dc:creator>Jane Doe</dc:creator>
</item>
</channel>
</rss>
XML;
$xml = simplexml_load_string($rss);
$item = $xml->channel->item;
// Access the dc: namespace by URI
$dc = $item->children('http://purl.org/dc/elements/1.1/');
echo $dc->creator . "\n"; // Jane DoeModifica e creazione di XML
SimpleXML può modificare nodi esistenti, aggiungerne di nuovi e serializzare il risultato. Si assegna un valore a una proprietà per modificarlo, si chiama addChild() per aggiungere un elemento e addAttribute() per aggiungere un attributo. asXML() restituisce il documento come stringa, oppure lo scrive su un file se viene fornito un percorso.
<?php
$book = simplexml_load_string('<book><title>Old Title</title><price>10.00</price></book>');
$book->title = 'New Title'; // change an existing value
$book->price = '12.50';
$book->addChild('author', 'Jane Doe'); // add a new element
$book->addAttribute('id', '42'); // add an attribute
echo $book->asXML();Output:
<?xml version="1.0"?>
<book id="42"><title>New Title</title><price>12.50</price><author>Jane Doe</author></book>Passare un nome file — $book->asXML('book.xml') — scrive il documento su disco e restituisce true in caso di successo. Consultare asXML() per la documentazione completa.
Gestione degli errori di analisi
Se l'XML è malformato, le funzioni di caricamento restituiscono false ed emettono avvisi PHP. Per catturare gli errori silenziosamente e esaminarli autonomamente, abilitare la gestione interna degli errori con libxml_use_internal_errors() e recuperarli con libxml_get_errors().
<?php
libxml_use_internal_errors(true);
$broken = "<library><book><title>Unclosed</book></library>";
$xml = simplexml_load_string($broken);
if ($xml === false) {
echo "Failed to parse XML:\n";
foreach (libxml_get_errors() as $error) {
echo trim($error->message) . "\n";
}
libxml_clear_errors();
}Output:
Failed to parse XML:
Opening and ending tag mismatch: title line 1 and book
Opening and ending tag mismatch: book line 1 and library
Premature end of data in tag library line 1Verificare sempre il valore restituito prima di utilizzare il risultato — trattare un false come un oggetto causa errori del tipo "attempt to read property on bool" a valle.
Riepilogo
- Caricare XML con
simplexml_load_string(),simplexml_load_file()onew SimpleXMLElement(); l'oggetto restituito è l'elemento radice. - Leggere gli elementi figlio come proprietà e gli attributi come chiavi array; effettuare il cast a
(string),(int)o(float)prima di confrontare o calcolare. - Usare
xpath()per il filtraggio e le query profonde, echildren()/attributes()con un URI per i documenti con namespace. - Modificare con l'assegnazione di proprietà,
addChild()eaddAttribute(), poi serializzare conasXML(). - Proteggere l'input malformato con
libxml_use_internal_errors()elibxml_get_errors().
Per approfondimenti, vedere Ottenere valori di nodi con SimpleXML, la panoramica del parser SimpleXML e le funzioni libxml di basso livello.