W3docs

PHP XML DOM

Aprende a usar la extensión DOM de PHP para cargar, crear, modificar, consultar con XPath y guardar documentos XML, con ejemplos ejecutables.

Para qué sirve la extensión DOM

La extensión DOM (Document Object Model) representa un documento XML como un árbol de nodos en memoria. Cada elemento, atributo, fragmento de texto y comentario es un objeto nodo que se puede leer, mover, agregar o eliminar. Como el documento completo se carga en RAM, el DOM es la herramienta adecuada cuando necesitas modificar XML, construir un documento desde cero o ejecutar consultas XPath que recorren el árbol.

Esta página cubre cómo cargar, crear, modificar, consultar y guardar XML con DOMDocument. Las ventajas y desventajas frente a las alternativas más ligeras son:

  • Usa la extensión SimpleXML cuando solo necesites leer XML bien formado rápidamente con el mínimo código.
  • Usa el XML Parser (Expat) para procesamiento por eventos de archivos muy grandes que no deben mantenerse completamente en memoria.
  • Recurre al DOM (esta página) cuando necesites control completo de lectura/escritura y XPath.

El DOM y libxml comparten un sistema de errores; consulta PHP libxml para gestionar errores de análisis.

Habilitar la extensión

La extensión DOM se incluye con PHP y está habilitada por defecto en la mayoría de las compilaciones (forma parte del paquete php-xml en Debian/Ubuntu). Puedes confirmar que está disponible:

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

Si no está disponible, instala el paquete php-xml para tu plataforma, o habilita extension=dom en php.ini, y reinicia tu servidor web.

Cargar un documento XML

Crea un DOMDocument y carga XML desde una cadena con loadXML() o desde un archivo con load(). Activa primero libxml_use_internal_errors(true) para que el marcado malformado no genere advertencias — así recopilas los errores tú mismo.

<?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";
}

Salida:

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

getElementsByTagName() devuelve un DOMNodeList activo sobre el que puedes iterar directamente con foreach — generalmente es más claro que recorrer childNodes, que también incluye los nodos de texto de espacio en blanco entre elementos.

Crear un documento XML desde cero

Construye un documento creando nodos en el DOMDocument y añadiéndolos a un padre. Establece formatOutput = true para obtener una salida indentada y legible por humanos de saveXML().

<?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();

Salida:

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

Métodos clave utilizados aquí:

  • createElement($name, $value) — crea un elemento, opcionalmente con contenido de texto.
  • setAttribute($name, $value) — agrega o sobreescribe un atributo en un elemento.
  • appendChild($node) — adjunta un nodo como el último hijo de su padre.

Atención: pasar texto directamente a createElement('title', $userInput) no escapa &, < ni > de forma fiable. Para texto no confiable, añade un nodo de texto en su lugar: $el->appendChild($doc->createTextNode($userInput)), que siempre escapa los caracteres especiales.

Modificar y eliminar nodos

Como todo el árbol está en memoria, puedes cambiar el texto, actualizar atributos y eliminar elementos antes de guardar. Una forma limpia de localizar el nodo correcto es XPath (cubierto a continuación), pero aquí lo usamos directamente:

<?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();

Salida:

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

</books>

Para eliminar un nodo debes llamar a removeChild() en su padre, por eso $second->parentNode->removeChild($second) es el patrón habitual. Asignar a nodeValue reemplaza el contenido de texto de un elemento.

Consultar con XPath

DOMXPath permite seleccionar nodos con expresiones de ruta en lugar de recorrer el árbol manualmente — mucho más conciso que los bucles anidados.

<?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";

Salida:

PHP for Beginners
Advanced XML
Book 2: Advanced XML

Patrones XPath comunes:

ExpresiónSelecciona
//titleTodos los elementos <title> a cualquier profundidad
/books/bookElementos <book> hijos directos de la raíz <books>
//book[@id="2"]Elementos <book> con el atributo id="2"
//book/@idLos nodos de atributo id de cada <book>
//book[1]El primer <book> (los índices XPath empiezan en 1)

Guardar en un archivo

Persiste el árbol en memoria con save(), que devuelve false en caso de error (por ejemplo, un directorio sin permisos de escritura).

<?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() (sin argumentos) cuando quieras el XML como una cadena — útil para devolverlo desde una API o mostrarlo en una respuesta.

Resumen

  • DOMDocument carga un documento XML completo en un árbol mutable de nodos.
  • Usa loadXML() / load() para leer, createElement() y appendChild() para construir, y removeChild() para eliminar.
  • DOMXPath::query() selecciona nodos con expresiones de ruta concisas.
  • save() escribe en un archivo; saveXML() devuelve el documento como una cadena.
  • Elige el DOM cuando necesites escribir o consultar XML; elige SimpleXML para lecturas rápidas y el XML Parser para procesar archivos enormes en streaming.

Práctica

Práctica
¿Qué puedes hacer con el PHP XML DOM?
¿Qué puedes hacer con el PHP XML DOM?
Was this page helpful?