2010-03-18 22 views
5

Estoy usando el DOM extension para analizar un archivo xml que contiene xml namespaces. Pensaría que las declaraciones del espacio de nombres se tratan como cualquier otro atributo, pero mis pruebas parecen estar en desacuerdo. Tengo un documento que comienza así:PHP: recuperar todos los espacios de nombres declarados de un DOMElement

<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns="http://purl.org/rss/1.0/" 
    xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" 
    xmlns:prism="http://purl.org/rss/1.0/modules/prism/" 
    xmlns:admin="http://webns.net/mvcb/" 
    > 

Y un código de prueba como esta:

$doc = new DOMDocument(); 
$doc->loadXml(file_get_contents('/home/soulmerge/tmp/rss1.0/recent.xml')); 
$root = $doc->documentElement; 
var_dump($root->tagName); 
# prints 'string(7) "rdf:RDF"' 
var_dump($root->attributes->item(0)); 
# prints 'NULL' 
var_dump($root->getAttributeNode('xmlns')); 
# prints 'object(DOMNameSpaceNode)#3 (0) {}' 

Así que las preguntas son:

  1. ¿Alguien sabe donde puedo encontrar la documentación de DOMNameSpaceNode? A search on php.net no produce ningún resultado útil.
  2. ¿Cómo se extraen todas las declaraciones del espacio de nombres de ese elemento DOMElement?

Respuesta

9

A menos que haya una manera más directa, puede usar XPath y su namespace axis.
p.

<?php 
$doc = new DOMDocument; 
$doc->loadxml('<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns="http://purl.org/rss/1.0/" 
    xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" 
    xmlns:prism="http://purl.org/rss/1.0/modules/prism/" 
    xmlns:admin="http://webns.net/mvcb/" 
    > 
... 
</rdf:RDF>'); 
$context = $doc->documentElement; 

$xpath = new DOMXPath($doc); 
foreach($xpath->query('namespace::*', $context) as $node) { 
    echo $node->nodeValue, "\n"; 
} 

impresiones

http://www.w3.org/XML/1998/namespace 
http://webns.net/mvcb/ 
http://purl.org/rss/1.0/modules/prism/ 
http://purl.org/rss/1.0/modules/syndication/ 
http://purl.org/dc/elements/1.1/ 
http://purl.org/rss/1.0/modules/taxonomy/ 
http://purl.org/rss/1.0/ 
http://www.w3.org/1999/02/22-rdf-syntax-ns# 

editar y por cierto: no he encontrado documentación para DOMNameSpaceNode bien. Pero se puede "deducir" (parte de) su funcionalidad desde el código fuente en ext/DOM/php_dom.c
no parece exponer cualquier método y expone las propiedades

"nodeName", "nodeValue", "nodeType", 
"prefix", "localName", "namespaceURI", 
"ownerDocument", "parentNode" 

todos manejados por el mismas funciones que las propiedades de DOMNode correspondientes.

+0

Muchas gracias, esta es definitivamente una solución de trabajo. Supongo que tendré que esperar hasta que la documentación de php se actualice para que la implementación sea correcta. – soulmerge

2

Nota, que

echo $root->getAttributeNode('xmlns')->nodeValue . "\n"; 
echo $root->getAttribute('xmlns') . "\n"; 
echo $root->getAttribute('xmlns:syn') . "\n"; 

todo el trabajo como se esperaba, e imprimir

http://purl.org/rss/1.0/ 
http://purl.org/rss/1.0/ 
http://purl.org/rss/1.0/modules/syndication/ 

porque DOMNameSpaceNode es un nodo, no un NodeCollection.

Simplemente aclarando que, a menos que algo en la extensión PHP DOM cambie, XPath (como lo explica VolkerK) es la única forma nativa de obtener todos los espacios de nombres, independientemente de la documentación.

Cuestiones relacionadas