W3docs

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); // SimpleXMLElement

Lettura 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 — science

Attenzione: un elemento a cui si accede in questo modo è un SimpleXMLElement, non una stringa. $book->price viene stampato come testo grazie al suo metodo __toString(), ma per operazioni aritmetiche o confronti rigorosi è necessario effettuare un cast: (float) $book->price oppure (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 Time

Lavorare 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 Doe

Modifica 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 1

Verificare 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.

  • Caricare XML con simplexml_load_string(), simplexml_load_file() o new 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, e children()/attributes() con un URI per i documenti con namespace.
  • Modificare con l'assegnazione di proprietà, addChild() e addAttribute(), poi serializzare con asXML().
  • Proteggere l'input malformato con libxml_use_internal_errors() e libxml_get_errors().

Per approfondimenti, vedere Ottenere valori di nodi con SimpleXML, la panoramica del parser SimpleXML e le funzioni libxml di basso livello.

Esercitazione

Pratica
Cos'è PHP SimpleXML?
Cos'è PHP SimpleXML?
Was this page helpful?