2010-03-18 15 views
5

Używam DOM extension do analizy pliku xml zawierającego xml namespaces. Wydaje mi się, że deklaracje przestrzeni nazw traktowane są jak każdy inny atrybut, ale moje testy się nie zgadzają. Mam dokument, który zaczyna się tak:PHP: pobranie wszystkich zadeklarowanych przestrzeni nazw 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/" 
    > 

i kod testu tak:

$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) {}' 

więc pytania są:

  1. Czy ktoś wie, gdzie mogę znaleźć w dokumentacji z DOMNameSpaceNode? A search on php.net nie daje żadnych użytecznych wyników.
  2. Jak wyodrębnić wszystkie deklaracje przestrzeni nazw z tego DOMElement?

Odpowiedz

9

O ile nie istnieje bardziej bezpośredni sposób, można użyć XPath i jego namespace axis.
np.

<?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"; 
} 

drukuje

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# 

edytować i btw: ja nie znalazłem dokumentacji dla DOMNameSpaceNode albo. Ale można „odjąć” (części) jego funkcjonalność z kodu źródłowego w ext/DOM/php_dom.c
nie wydaje się, aby wystawiać żadnych metod i eksponuje właściwości

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

wszystkie obsługiwane przez takie same funkcje jak odpowiednie właściwości DOMNode.

+0

Wielkie dzięki, to zdecydowanie działające rozwiązanie. Chyba będę musiał poczekać, aż dokumentacja php zostanie zaktualizowana, aby uzyskać właściwą implementację. – soulmerge

2

Zauważ, że

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

wszystko działa zgodnie z oczekiwaniami, i wydrukować

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

ponieważ DOMNameSpaceNode jest węzłem, a nie NodeCollection.

Po prostu wyjaśniając, że jeśli coś w rozszerzeniu DOM DOM nie ulegnie zmianie, XPath (jak wyjaśnił VolkerK) jest jedynym rodzimym sposobem uzyskania wszystkich przestrzeni nazw, niezależnie od dokumentacji.

Powiązane problemy