SimpleXML en PHP: leer, recorrer y crear documentos XML de forma sencilla

SimpleXML es la extensión de PHP pensada para leer y crear documentos XML de forma rápida y sin complicaciones. Convierte un documento XML en un objeto PHP con el que puedes navegar usando la sintaxis de propiedades y corchetes, como si fuese un array o un objeto normal. Para la mayoría de los casos —feeds RSS, configuraciones, respuestas de APIs antiguas, sitemaps— es la herramienta más cómoda del lenguaje.

Cargar un documento XML

Dos funciones de entrada: simplexml_load_file() para cargar desde un fichero o URL, y simplexml_load_string() para parsear un string:

<?php
// Desde fichero o URL
$xml = simplexml_load_file('catalogo.xml');
$xml = simplexml_load_file('https://example.com/feed.xml');

// Desde string
$cadena = '<?xml version="1.0" encoding="UTF-8"?>
<producto>
  <nombre>Teclado mecánico</nombre>
  <precio moneda="EUR">89.99</precio>
  <stock>42</stock>
</producto>';

$xml = simplexml_load_string($cadena);

// Manejo de errores
libxml_use_internal_errors(true);
$xml = simplexml_load_string($cadena_invalida);
if ($xml === false) {
    foreach (libxml_get_errors() as $error) {
        echo $error->message;
    }
}

Acceder a elementos y atributos

<?php
$xml = simplexml_load_string('
<tienda>
  <producto id="1" categoria="informatica">
    <nombre>Teclado mecánico</nombre>
    <precio moneda="EUR">89.99</precio>
    <descripcion>Switches Cherry MX Red, retroiluminación RGB</descripcion>
  </producto>
</tienda>');

// Acceder a elementos
echo $xml->producto->nombre;       // Teclado mecánico
echo $xml->producto->precio;       // 89.99
echo (float)$xml->producto->precio;  // 89.99 (como float)

// Acceder a atributos
echo $xml->producto['id'];            // 1
echo $xml->producto['categoria'];     // informatica
echo $xml->producto->precio['moneda'];  // EUR

Recorrer elementos con foreach

<?php
$xml = simplexml_load_string('
<catalogo>
  <producto id="1"><nombre>Teclado</nombre><precio>89.99</precio></producto>
  <producto id="2"><nombre>Ratón</nombre><precio>29.99</precio></producto>
  <producto id="3"><nombre>Monitor</nombre><precio>299.00</precio></producto>
</catalogo>');

foreach ($xml->producto as $prod) {
    $id     = (int)$prod['id'];
    $nombre = (string)$prod->nombre;
    $precio = (float)$prod->precio;
    echo "$id: $nombre — {$precio}€n";
}

// Convertir a array si lo necesitas para JSON
$datos = json_decode(json_encode($xml), true);

Consultas XPath

XPath permite seleccionar nodos con expresiones potentes. Es la forma más eficiente de buscar en documentos complejos:

<?php
$xml = simplexml_load_file('productos.xml');

// Todos los productos de la categoría "informatica"
$informatica = $xml->xpath('//producto[@categoria="informatica"]');

// Productos con precio menor de 50
$baratos = $xml->xpath('//producto[precio < 50]');

// El nombre del segundo producto
$segundo = $xml->xpath('//producto[2]/nombre');
echo (string)$segundo[0];

// XPath con namespace
$xml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');
$entradas = $xml->xpath('//atom:entry');

// Buscar por texto contenido
$coincidencias = $xml->xpath('//nombre[contains(text(), "Teclado")]');

Leer un feed RSS real

<?php
function leerRSS(string $url): array {
    libxml_use_internal_errors(true);
    $xml = simplexml_load_file($url);

    if ($xml === false) {
        return [];
    }

    $articulos = [];
    foreach ($xml->channel->item as $item) {
        $articulos[] = [
            'titulo'      => (string)$item->title,
            'enlace'      => (string)$item->link,
            'descripcion' => (string)$item->description,
            'fecha'       => (string)$item->pubDate,
            'autor'       => (string)($item->author ?? $item->children('dc', true)->creator ?? ''),
        ];
    }
    return $articulos;
}

$noticias = leerRSS('https://feeds.elpais.com/mrss-s/pages/ep/site/elpais.com/portada');
foreach (array_slice($noticias, 0, 5) as $noticia) {
    echo $noticia['titulo'] . "n";
}

Crear documentos XML con addChild() y asXML()

<?php
// Crear desde cero
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><catalogo/>');

$prod1 = $xml->addChild('producto');
$prod1->addAttribute('id', '1');
$prod1->addChild('nombre', 'Teclado mecánico');
$prod1->addChild('precio', '89.99')->addAttribute('moneda', 'EUR');
$prod1->addChild('stock', '42');

$prod2 = $xml->addChild('producto');
$prod2->addAttribute('id', '2');
$prod2->addChild('nombre', 'Ratón inalámbrico');
$prod2->addChild('precio', '29.99')->addAttribute('moneda', 'EUR');

// Guardar en fichero
$xml->asXML('catalogo.xml');

// Obtener como string
$cadena = $xml->asXML();

// Formatear con indentación (vía DOMDocument)
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();

Crear un sitemap XML

<?php
function generarSitemap(array $urls): string {
    $xml = new SimpleXMLElement(
        '<?xml version="1.0" encoding="UTF-8"?>' .
        '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"/>'
    );

    foreach ($urls as $entrada) {
        $url = $xml->addChild('url');
        $url->addChild('loc',        htmlspecialchars($entrada['loc']));
        $url->addChild('lastmod',    $entrada['lastmod']);
        $url->addChild('changefreq', $entrada['changefreq'] ?? 'weekly');
        $url->addChild('priority',   $entrada['priority']   ?? '0.5');
    }

    return $xml->asXML();
}

$sitemap = generarSitemap([
    ['loc' => 'https://ejemplo.com/', 'lastmod' => '2026-09-01', 'priority' => '1.0'],
    ['loc' => 'https://ejemplo.com/articulos/', 'lastmod' => '2026-09-15'],
]);
file_put_contents('sitemap.xml', $sitemap);

SimpleXML vs DOMDocument

Ambas extensiones procesan XML pero tienen enfoques distintos:

  • SimpleXML: sintaxis sencilla, ideal para leer y modificar documentos bien formados. Menos código para casos simples.
  • DOMDocument: más potente, soporta HTML malformado, control fino de nodos, necesaria para manipulación compleja o scraping.
  • Pueden combinarse: dom_import_simplexml() convierte un nodo SimpleXML en un nodo DOM y viceversa con simplexml_import_dom().

Errores frecuentes

  • No hacer cast del valor: los elementos SimpleXML son objetos SimpleXMLElement. Haz siempre (string), (int) o (float) antes de usar el valor en comparaciones o funciones PHP.
  • Namespaces ignorados: si el XML usa namespaces (xmlns:atom="..."), accede a sus elementos con $xml->children('atom', true)->entry o registra el namespace para XPath.
  • Errores silenciosos sin libxml_use_internal_errors(true): sin esto, un XML inválido lanza warnings en lugar de devolver false, lo que dificulta la captura de errores.
  • Caracteres especiales en addChild: <, > y & deben pasarse como texto plano; SimpleXML los escapa. Si pasas HTML dentro de un nodo, usa addChild normalmente y deja que SimpleXML lo escape.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP