getDocNamespaces()
SimpleXML é uma extensão PHP que fornece uma API simples para trabalhar com documentos XML. Saiba como usar SimpleXMLElement::getDocNamespaces().
Introdução
SimpleXML é uma extensão PHP que fornece uma API simples e orientada a objetos para leitura de documentos XML. Os namespaces XML permitem que dois vocabulários compartilhem um mesmo documento sem que os nomes dos elementos entrem em conflito — cada namespace é identificado por uma URI e geralmente referenciado por meio de um prefixo curto (por exemplo, bk em <bk:title>).
SimpleXMLElement::getDocNamespaces() é o método que informa quais namespaces um documento declara. Você geralmente o utiliza antes de chamar children() ou xpath() em dados com namespace, pois precisa das URIs para endereçar esses nós. Este capítulo aborda a sintaxe, a diferença que o sinalizador $recursive faz, a armadilha do namespace padrão e como ele difere do método de nome similar getNamespaces().
Sintaxe
public SimpleXMLElement::getDocNamespaces(bool $recursive = false, bool $from_root = true): array$recursive— quandofalse(o padrão), apenas os namespaces declarados no elemento raiz são retornados. Quandotrue, toda a árvore do documento é percorrida e os namespaces declarados em qualquer descendente também são incluídos.$from_root— quandotrue(o padrão), a varredura começa a partir da raiz do documento, mesmo que o método seja chamado em um sub-elemento. Defina comofalsepara varrer apenas a partir do nó atual.
O valor de retorno é um array associativo que mapeia cada prefixo de namespace (a string antes dos dois pontos) à sua URI.
Exemplo básico
Este documento declara um namespace, bk, em seu elemento raiz:
Saída:
Prefix: bk, URI: https://example.com/booksO método retorna um array associativo, portanto um foreach com $prefix => $uri percorre todas as declarações em um único laço.
O que $recursive realmente muda
O sinalizador só importa quando um namespace é declarado abaixo da raiz. Aqui lib está na raiz, mas dc é declarado em um elemento <details> aninhado:
<?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));Saída:
Root only:
Array
(
[lib] => https://example.com/library
)
Whole document:
Array
(
[lib] => https://example.com/library
[dc] => https://purl.org/dc/elements/1.1/
)Passe true sempre que não puder garantir que todos os namespaces estejam declarados na raiz — feeds e documentos agregados frequentemente declaram extras mais fundo na árvore.
A armadilha do namespace padrão
Um namespace declarado com xmlns="..." (sem prefixo) é o namespace padrão do documento. getDocNamespaces() o retorna sob uma chave de string vazia, não sob a 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));Saída:
Array
(
[] => http://www.w3.org/2005/Atom
[media] => http://search.yahoo.com/mrss/
)Você precisará dessa URI de string vazia para ler nós com namespace padrão, por exemplo, $xml->children('http://www.w3.org/2005/Atom') ou registrando-a com registerXPathNamespace() antes de uma consulta xpath().
getDocNamespaces() vs getNamespaces()
Esses dois são fáceis de confundir:
| Método | Escopo |
|---|---|
getDocNamespaces() | Namespaces declarados no documento (os atributos xmlns), independentemente de serem utilizados. |
getNamespaces() | Namespaces efetivamente utilizados pelo elemento e (opcionalmente) por seus filhos — namespaces declarados mas não utilizados são excluídos. |
Em resumo: getDocNamespaces() responde "o que este documento define?" enquanto getNamespaces() responde "o que esta parte do documento usa?".
Quando usá-lo
- Antes de consultar nós com namespace — alimente as URIs retornadas em
children($uri)ouregisterXPathNamespace(). - Ao consumir XML de terceiros (RSS/Atom, SOAP, RSS Media, SVG) onde você não controla os prefixos.
- Para inspecionar ou validar as declarações de namespace de um documento desconhecido.
Conclusão
SimpleXMLElement::getDocNamespaces() retorna um array associativo dos prefixos de namespace e URIs declarados em um documento XML. Use o valor padrão (false) quando todos os namespaces estiverem na raiz, e passe true para varrer toda a árvore. Lembre-se de que o namespace padrão (sem prefixo) é retornado sob uma chave de string vazia, e recorra a getNamespaces() quando se importar com quais namespaces são realmente utilizados, em vez de apenas declarados.