W3docs

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 — quando false (o padrão), apenas os namespaces declarados no elemento raiz são retornados. Quando true, toda a árvore do documento é percorrida e os namespaces declarados em qualquer descendente também são incluídos.
  • $from_root — quando true (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 como false para 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:

php— editable, runs on the server

Saída:

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

O 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étodoEscopo
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) ou registerXPathNamespace().
  • 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.

Prática

Prática
O que SimpleXMLElement::getDocNamespaces(true) retorna que getDocNamespaces() (o padrão) não retorna?
O que SimpleXMLElement::getDocNamespaces(true) retorna que getDocNamespaces() (o padrão) não retorna?
Was this page helpful?