W3docs

PHP XML DOM

Scopri come usare l'estensione DOM di PHP per caricare, creare, modificare, interrogare (con XPath) e salvare documenti XML, con esempi eseguibili.

A cosa serve l'estensione DOM

L'estensione DOM (Document Object Model) rappresenta un documento XML in memoria come un albero di nodi. Ogni elemento, attributo, frammento di testo e commento è un oggetto nodo che puoi leggere, spostare, aggiungere o eliminare. Poiché l'intero documento viene caricato in RAM, il DOM è lo strumento giusto quando devi modificare un XML, costruire un documento da zero o eseguire query XPath che si muovono liberamente nell'albero.

Questa pagina tratta il caricamento, la creazione, la modifica, l'interrogazione e il salvataggio di XML con DOMDocument. I compromessi rispetto alle alternative più leggere sono questi:

  • Usa l'estensione SimpleXML quando ti serve soltanto leggere rapidamente un XML ben formato con poco codice.
  • Usa l'XML Parser (Expat) per l'elaborazione in streaming, basata su eventi, di file molto grandi che non devono essere tenuti interamente in memoria.
  • Ricorri al DOM (questa pagina) quando ti serve il pieno controllo in lettura e scrittura, oltre a XPath.

Il DOM e libxml condividono lo stesso sistema di gestione degli errori; consulta PHP libxml per gestire gli errori di parsing.

Abilitare l'estensione

L'estensione DOM è inclusa in PHP ed è abilitata di default nella maggior parte delle build (fa parte del pacchetto php-xml su Debian/Ubuntu). Puoi verificare che sia disponibile:

<?php
var_dump(extension_loaded('dom')); // bool(true)

Se manca, installa il pacchetto php-xml per la tua piattaforma oppure abilita extension=dom in php.ini, quindi riavvia il web server.

Caricare un documento XML

Crea un DOMDocument e carica l'XML da una stringa con loadXML() oppure da un file con load(). Attiva prima libxml_use_internal_errors(true) in modo che un markup malformato non riempia l'output di warning: gli errori li raccogli tu stesso.

<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book id="1"><title>PHP for Beginners</title></book>
  <book id="2"><title>Advanced XML</title></book>
</books>
XML;

libxml_use_internal_errors(true);
$doc = new DOMDocument();

if (!$doc->loadXML($xml)) {
    foreach (libxml_get_errors() as $error) {
        echo trim($error->message) . "\n";
    }
    libxml_clear_errors();
    exit;
}

$root = $doc->documentElement;
echo "Root element: {$root->nodeName}\n";

foreach ($root->getElementsByTagName('title') as $title) {
    echo "Title: {$title->nodeValue}\n";
}

Output:

Root element: books
Title: PHP for Beginners
Title: Advanced XML

getElementsByTagName() restituisce un DOMNodeList live su cui puoi iterare direttamente con foreach: di solito è più chiaro che scorrere childNodes, che include anche i nodi di testo con gli spazi bianchi tra un elemento e l'altro.

Creare un documento XML da zero

Costruisci un documento creando nodi sul DOMDocument e aggiungendoli a un nodo genitore. Imposta formatOutput = true per ottenere da saveXML() un output indentato e leggibile.

<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;

$root = $doc->createElement('books');
$doc->appendChild($root);

$book = $doc->createElement('book');
$book->setAttribute('id', '1');
$root->appendChild($book);

$title = $doc->createElement('title', 'PHP for Beginners');
$book->appendChild($title);

echo $doc->saveXML();

Output:

<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book id="1">
    <title>PHP for Beginners</title>
  </book>
</books>

I metodi principali usati qui:

  • createElement($name, $value) — crea un elemento, con contenuto testuale opzionale.
  • setAttribute($name, $value) — aggiunge o sovrascrive un attributo di un elemento.
  • appendChild($node) — collega un nodo come ultimo figlio del suo genitore.

Attenzione: passare il testo direttamente a createElement('title', $userInput) non esegue l'escape di &, < o > in modo affidabile. Per un testo non attendibile, aggiungi invece un nodo di testo: $el->appendChild($doc->createTextNode($userInput)), che esegue sempre l'escape dei caratteri speciali.

Modificare ed eliminare nodi

Poiché l'intero albero è in memoria, puoi cambiare il testo, aggiornare gli attributi e rimuovere elementi prima di salvare. Un modo pulito per individuare il nodo giusto è XPath (trattato nella prossima sezione), ma qui lo usiamo già in linea:

<?php
$xml = <<<XML
<books>
  <book id="1"><title>PHP for Beginners</title></book>
  <book id="2"><title>Advanced XML</title></book>
</books>
XML;

$doc = new DOMDocument();
$doc->formatOutput = true;
$doc->loadXML($xml);

$xpath = new DOMXPath($doc);

// Rename the first title
$first = $xpath->query('//book[@id="1"]/title')->item(0);
$first->nodeValue = 'PHP Essentials';

// Remove the second book
$second = $xpath->query('//book[@id="2"]')->item(0);
$second->parentNode->removeChild($second);

echo $doc->saveXML();

Output:

<?xml version="1.0"?>
<books>
  <book id="1"><title>PHP Essentials</title></book>

</books>

Per eliminare un nodo si chiama removeChild() sul suo genitore, ed ecco perché $second->parentNode->removeChild($second) è l'idioma abituale. Assegnare un valore a nodeValue sostituisce il contenuto testuale di un elemento.

Interrogare con XPath

DOMXPath permette di selezionare i nodi con espressioni di percorso invece di percorrere manualmente l'albero: è molto più conciso dei cicli annidati.

<?php
$xml = <<<XML
<books>
  <book id="1"><title>PHP for Beginners</title></book>
  <book id="2"><title>Advanced XML</title></book>
</books>
XML;

$doc = new DOMDocument();
$doc->loadXML($xml);

$xpath = new DOMXPath($doc);

// Every <title> anywhere in the document
foreach ($xpath->query('//title') as $node) {
    echo $node->nodeValue . "\n";
}

// The title of the book whose id is "2"
$result = $xpath->query('//book[@id="2"]/title');
echo "Book 2: " . $result->item(0)->nodeValue . "\n";

Output:

PHP for Beginners
Advanced XML
Book 2: Advanced XML

Pattern XPath comuni:

EspressioneSeleziona
//titleTutti gli elementi <title> a qualsiasi profondità
/books/bookGli elementi <book> figli diretti della radice <books>
//book[@id="2"]Gli elementi <book> con l'attributo id="2"
//book/@idI nodi attributo id di ogni <book>
//book[1]Il primo <book> (in XPath gli indici partono da 1)

Salvare su file

Rendi persistente l'albero in memoria con save(), che restituisce false in caso di errore (per esempio una directory non scrivibile).

<?php
$doc = new DOMDocument('1.0', 'UTF-8');
$doc->formatOutput = true;

$root = $doc->createElement('config');
$doc->appendChild($root);
$root->appendChild($doc->createElement('debug', 'false'));

if ($doc->save(__DIR__ . '/output.xml')) {
    echo 'Saved successfully.';
} else {
    echo 'Failed to save — check directory permissions.';
}

Usa saveXML() (senza argomenti) quando vuoi ottenere l'XML come stringa: è comodo per restituirlo da un'API o stamparlo in una risposta.

  • DOMDocument carica un intero documento XML in un albero di nodi modificabile.
  • Usa loadXML() / load() per leggere, createElement() e appendChild() per costruire e removeChild() per eliminare.
  • DOMXPath::query() seleziona i nodi con espressioni di percorso concise.
  • save() scrive su file; saveXML() restituisce il documento come stringa.
  • Scegli il DOM quando devi scrivere o interrogare XML; scegli SimpleXML per letture rapide e l'XML Parser per lo streaming di file enormi.

Pratica

Pratica
Cosa puoi fare con il DOM XML di PHP?
Cosa puoi fare con il DOM XML di PHP?
Was this page helpful?