SimpleXML in PHP: Una Guida Completa
SimpleXML è un potente strumento PHP per analizzare e manipolare dati XML. Scopri come usarlo con esempi pratici.
SimpleXML è un'estensione PHP integrata che trasforma un documento XML in un albero di oggetti che puoi leggere, scorrere e modificare con la normale sintassi PHP. Questo tutorial tratta il caricamento di XML, la lettura di elementi e attributi, la gestione dei namespace, la modifica dei nodi e la scrittura del risultato — con esempi eseguibili e le insidie più comuni.
Introduzione a SimpleXML
SimpleXML è un'estensione PHP che consente di analizzare e manipolare dati XML con pochissimo codice. È distinta dall'estensione DOM, ma entrambe si basano sulla stessa libreria libxml2, quindi condividono la sua gestione degli errori. Il compromesso è semplice:
- SimpleXML — ideale per leggere XML ben formato in cui si percorre principalmente una struttura nota. Accesso conciso, simile a un oggetto.
- DOM — migliore per modifiche intensive, spostamento di nodi, o quando si ha bisogno del pieno controllo sull'albero del documento.
SimpleXML è abilitato per impostazione predefinita nelle build PHP standard, quindi di solito non c'è nulla da installare.
Caricamento di XML
Ci sono due punti di ingresso. Usa simplexml_load_file() per un file o URL, e simplexml_load_string() per XML già presente in una stringa (ad esempio, una risposta API).
Poiché entrambe le funzioni si basano su libxml2, un documento malformato genera avvisi PHP e restituisce false. Passa sempre prima alla gestione interna degli errori con libxml_use_internal_errors() per poter ispezionare gli errori tu stesso invece di far trapelare gli avvisi nell'output:
Caricamento di un file XML
libxml_use_internal_errors(true);
$xml = simplexml_load_file('data.xml');
if ($xml === false) {
foreach (libxml_get_errors() as $error) {
echo trim($error->message), PHP_EOL;
}
die('Failed to load XML.');
}simplexml_load_string() funziona in modo identico ma accetta il testo XML direttamente:
Caricamento di XML da una stringa
$source = '<data><item><name>John Doe</name></item></data>';
$xml = simplexml_load_string($source);In entrambi i casi il valore restituito è un SimpleXMLElement che rappresenta l'elemento radice del documento.
Accesso agli Elementi
SimpleXML mappa ogni elemento figlio in una proprietà dell'oggetto genitore, accessibile con l'operatore PHP -> (non la notazione con punto — PHP non ha accesso ai membri con .). Gli elementi figlio ripetuti vengono indirizzati tramite indice. Considera questo XML:
Esempio XML
<data>
<item>
<name>John Doe</name>
<age>30</age>
</item>
<item>
<name>Jane Doe</name>
<age>28</age>
</item>
</data>Leggi il primo elemento, poi scorri tutti gli item con foreach:
Accesso ai valori degli elementi
// The first <item> (index 0)
$name = $xml->item[0]->name;
$age = $xml->item[0]->age;
// Iterate through all <item> elements
foreach ($xml->item as $item) {
echo $item->name . ' is ' . $item->age . ' years old.' . PHP_EOL;
}L'insidia del cast a stringa
$item->name non è una stringa — è un SimpleXMLElement. Sembra una stringa quando viene usata con echo perché l'elemento viene automaticamente convertito nei contesti stringa. Se lo memorizzi in un array, lo passi a json_encode(), o lo confronti in modo stretto, eseguine prima il cast esplicito:
$name = (string) $xml->item[0]->name; // plain string
$age = (int) $xml->item[0]->age; // plain intLettura degli Attributi
Gli attributi degli elementi vengono letti con la sintassi ad array, non con l'operatore ->. Dato <item id="1" status="active">, leggili in questo modo:
Accesso agli attributi
$id = (string) $xml->item[0]['id']; // "1"
$status = (string) $xml->item[0]['status']; // "active"
// Loop over every attribute on an element
foreach ($xml->item[0]->attributes() as $key => $value) {
echo "$key = $value" . PHP_EOL;
}Lavorare con i Namespace
XML che utilizza namespace (prefissi come <atom:link>) non verrà risolto tramite accesso diretto alle proprietà — devi registrare il namespace con children() o usare una query XPath. Questo è il motivo più comune per cui "l'elemento è vuoto" anche se è chiaramente nel file:
Elementi con namespace
$source = '<feed xmlns:atom="http://www.w3.org/2005/Atom">'
. '<atom:title>Hello</atom:title></feed>';
$xml = simplexml_load_string($source);
$atom = $xml->children('http://www.w3.org/2005/Atom');
echo (string) $atom->title; // "Hello"Query con XPath
Per qualcosa di più profondo di un figlio diretto, xpath() restituisce un array di elementi corrispondenti — molto più pulito che annidare loop:
// Every <name> anywhere under the root
foreach ($xml->xpath('//name') as $name) {
echo (string) $name . PHP_EOL;
}Modifica e Aggiunta di Elementi
Puoi cambiare un valore assegnandolo alla proprietà, e far crescere l'albero con addChild() / addAttribute():
Modifica e creazione di nodi
// Change existing values
$xml->item[0]->name = 'John Smith';
$xml->item[0]->age = 32;
// Add a brand-new child element and an attribute
$new = $xml->addChild('item');
$new->addChild('name', 'New Person');
$new->addAttribute('id', '99');L'assegnazione di un valore sostituisce il contenuto testuale dell'elemento; addChild() aggiunge un nuovo elemento invece di sovrascriverne uno.
Conversione in XML
Usa il metodo asXML() per serializzare l'albero (eventualmente modificato) in una stringa, poi scrivilo con file_put_contents():
Salvataggio delle modifiche in XML
file_put_contents('data.xml', $xml->asXML());Chiamato senza argomento, asXML() restituisce il documento completo come stringa inclusa la dichiarazione <?xml version="1.0"?> — esattamente quello che vuoi per il salvataggio. Chiamalo su un elemento figlio ($xml->item[0]->asXML()) per ottenere solo quel frammento, senza la dichiarazione.
Conclusione
SimpleXML è il modo più rapido per leggere e modificare leggermente XML ben formato in PHP: carica con simplexml_load_file() o simplexml_load_string(), percorri l'albero con -> e l'indicizzazione degli array, leggi gli attributi con [], e serializza con asXML(). Ricorda le due insidie ricorrenti — esegui il cast degli elementi in stringhe prima di riutilizzarli, e registra i namespace prima di accedere ai nodi con prefisso. Per la modifica programmatica e su larga scala dei documenti, usa l'estensione DOM. Per approfondire, continua con PHP SimpleXML e lettura dei dati con SimpleXML get.