开发者

PHP: retrieve all declared namespaces of a DOMElement

开发者 https://www.devze.com 2022-12-24 10:21 出处:网络
I am using the DOM extension to parse an xml file containing xml namespaces. I would have thought that namespace declarations are treated just like any other attribute, but my tests seem to disagree.

I am using the DOM extension to parse an xml file containing xml namespaces. I would have thought that namespace declarations are treated just like any other attribute, but my tests seem to disagree. I have a document that starts like this:

<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/module开发者_StackOverflow社区s/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/"
    >

And a test code like this:

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

So the questions are:

  1. Does anyone know where could I find the documentation of DOMNameSpaceNode? A search on php.net does not yield any useful result.
  2. How do I extract all those namespace declarations from that DOMElement?


Unless there is a more direct way you can use XPath and its namespace axis.
e.g.

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

prints

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#

edit and btw: I haven't found documentation for DOMNameSpaceNode either. But you can "deduct" (parts of) its functionality from the source code in ext/dom/php_dom.c
It doesn't seem to expose any methods and exposes the properties

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

all handled by the same functions as the corresponding DOMNode properties.


Note, that

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

all work as expected, and print out

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

because DOMNameSpaceNode is a Node, not a NodeCollection.

Just clarifying, that, unless something in PHP DOM extension changes, XPath (as explained by VolkerK) is the only native way to get all the namespaces, regardless of documentation.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号