7

我正在使用DOM 扩展来解析包含xml 命名空间的 xml 文件。我原以为命名空间声明就像任何其他属性一样被对待,但我的测试似乎不同意。我有一个这样开头的文件:

<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/"
    >

和这样的测试代码:

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

所以问题是:

  1. 有谁知道我在哪里可以找到的文档DOMNameSpaceNode?在php.net 上搜索不会产生任何有用的结果。
  2. 如何从该 DOMElement 中提取所有这些命名空间声明?
4

2 回答 2

12

除非有更直接的方式可以使用 XPath 及其命名空间轴
例如

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

印刷

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#

编辑顺便说一句:我也没有找到 DOMNameSpaceNode 的文档。但是您可以从 ext/dom/php_dom.c 中的源代码中“扣除”(部分)其功能
它似乎没有公开任何方法并公开属性

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

所有这些都由与相应 DOMNode 属性相同的函数处理。

于 2010-03-18T14:13:05.040 回答
5

注意

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

一切都按预期工作,并打印出来

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

因为 DOMNameSpaceNode 是一个节点,而不是一个 NodeCollection。

只是澄清一下,除非 PHP DOM 扩展中的某些内容发生更改,否则 XPath(如 VolkerK 所解释的)是获取所有名称空间的唯一本地方式,而不管文档如何。

于 2011-06-27T16:35:58.847 回答