W3docs

getDocNamespaces()

SimpleXML es una extensión de PHP que ofrece una API sencilla para trabajar con documentos XML. Aprende a usar SimpleXMLElement::getDocNamespaces().

Introducción

SimpleXML es una extensión de PHP que proporciona una API sencilla y orientada a objetos para leer documentos XML. Los espacios de nombres XML permiten que dos vocabularios compartan un mismo documento sin que sus nombres de elementos entren en conflicto — cada espacio de nombres se identifica mediante una URI y generalmente se referencia con un breve prefijo (por ejemplo, bk en <bk:title>).

SimpleXMLElement::getDocNamespaces() es el método que indica qué espacios de nombres declara un documento. Por lo general se usa antes de llamar a children() o xpath() sobre datos con espacios de nombres, ya que se necesitan las URIs para poder direccionar esos nodos. Este capítulo cubre la sintaxis, la diferencia que produce el indicador $recursive, el problema con el espacio de nombres predeterminado y cómo difiere del método getNamespaces(), que tiene un nombre muy similar.

Sintaxis

public SimpleXMLElement::getDocNamespaces(bool $recursive = false, bool $from_root = true): array
  • $recursive — cuando es false (el valor predeterminado), solo se devuelven los espacios de nombres declarados en el elemento raíz. Cuando es true, se analiza todo el árbol del documento y también se incluyen los espacios de nombres declarados en cualquier descendiente.
  • $from_root — cuando es true (el valor predeterminado), el análisis comienza desde la raíz del documento aunque se llame al método sobre un subelemento. Establézcalo en false para analizar solo desde el nodo actual hacia abajo.

El valor de retorno es un array asociativo que asigna cada prefijo de espacio de nombres (la cadena antes de los dos puntos) a su URI.

Ejemplo básico

Este documento declara un espacio de nombres, bk, en su elemento raíz:

php— editable, runs on the server

Salida:

Prefix: bk, URI: https://example.com/books

El método devuelve un array asociativo, por lo que un foreach con $prefix => $uri recorre cada declaración en un solo bucle.

Qué cambia realmente $recursive

El indicador solo importa cuando un espacio de nombres se declara por debajo de la raíz. Aquí lib está en la raíz, pero dc se declara en un elemento <details> anidado:

<?php

$xml = new SimpleXMLElement(
    '<library xmlns:lib="https://example.com/library">'
  . '  <lib:book>'
  . '    <details xmlns:dc="https://purl.org/dc/elements/1.1/">'
  . '      <dc:title>PHP Basics</dc:title>'
  . '    </details>'
  . '  </lib:book>'
  . '</library>'
);

echo "Root only:\n";
print_r($xml->getDocNamespaces(false));

echo "Whole document:\n";
print_r($xml->getDocNamespaces(true));

Salida:

Root only:
Array
(
    [lib] => https://example.com/library
)
Whole document:
Array
(
    [lib] => https://example.com/library
    [dc] => https://purl.org/dc/elements/1.1/
)

Pasa true siempre que no puedas garantizar que todos los espacios de nombres estén declarados en la raíz — los feeds y los documentos agregados suelen declarar extras más abajo en el árbol.

El problema con el espacio de nombres predeterminado

Un espacio de nombres declarado con xmlns="..." (sin prefijo) es el espacio de nombres predeterminado del documento. getDocNamespaces() lo devuelve bajo una clave de cadena vacía, no bajo la URI:

<?php

$xml = new SimpleXMLElement(
    '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">'
  . '<entry><title>Hello</title></entry>'
  . '</feed>'
);

print_r($xml->getDocNamespaces(true));

Salida:

Array
(
    [] => http://www.w3.org/2005/Atom
    [media] => http://search.yahoo.com/mrss/
)

Necesitarás esa URI de cadena vacía para leer los nodos con espacio de nombres predeterminado, p. ej. $xml->children('http://www.w3.org/2005/Atom') o registrándola con registerXPathNamespace() antes de una consulta xpath().

getDocNamespaces() vs getNamespaces()

Estos dos métodos son fáciles de confundir:

MétodoAlcance
getDocNamespaces()Espacios de nombres declarados en el documento (los atributos xmlns), independientemente de si algo los usa.
getNamespaces()Espacios de nombres realmente usados por el elemento y (opcionalmente) sus hijos — los espacios de nombres declarados pero no utilizados quedan excluidos.

En resumen: getDocNamespaces() responde "¿qué define este documento?" mientras que getNamespaces() responde "¿qué usa esta parte del documento?".

Cuándo usarlo

  • Antes de consultar nodos con espacios de nombres — introduce las URIs devueltas en children($uri) o registerXPathNamespace().
  • Al consumir XML de terceros (RSS/Atom, SOAP, RSS Media, SVG) donde no controlas los prefijos.
  • Para inspeccionar o validar las declaraciones de espacio de nombres de un documento desconocido.

Conclusión

SimpleXMLElement::getDocNamespaces() devuelve un array asociativo con los prefijos de espacio de nombres y las URIs declaradas en un documento XML. Usa el valor predeterminado (false) cuando todos los espacios de nombres están en la raíz, y pasa true para analizar todo el árbol. Recuerda que el espacio de nombres predeterminado (sin prefijo) se devuelve bajo una clave de cadena vacía, y recurre a getNamespaces() cuando te importa cuáles espacios de nombres se usan realmente y no solo cuáles están declarados.

Práctica

Práctica
¿Qué devuelve SimpleXMLElement::getDocNamespaces(true) que no devuelve getDocNamespaces() (el valor predeterminado)?
¿Qué devuelve SimpleXMLElement::getDocNamespaces(true) que no devuelve getDocNamespaces() (el valor predeterminado)?
Was this page helpful?