XPath不能匹配没有命名空间前缀的属性。

4

目前,我正在尝试通过PHP的SimpleXML读取Firefox扩展的不同install.rdf文件。

不幸的是,它们没有预定义的结构。它们总是使用两个命名空间:“http://www.w3.org/1999/02/22-rdf-syntax-ns#”和“http://www.mozilla.org/2004/em-rdf#”。

因此,我的想法是使用XPath来获取感兴趣的元素:

$xml = simplexml_load_string($installRDF);
$namespaces = $xml->getNameSpaces(true);
$xml->registerXPathNamespace('rdf', NS_RDF);
$main = $xml->xpath('/rdf:RDF/rdf:Description[@rdf:about="urn:mozilla:install-manifest"]');

但是在about属性的rdf前缀方面似乎存在问题,因为只有在RDF文件中也定义了前缀时,它才会返回结果。

所以这样可以:

<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
         xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

  <RDF:Description RDF:about="urn:mozilla:install-manifest">
    <em:id>extension@mozilla.org</em:id>
  </RDF:Description>
</RDF:RDF>

但是对于这个不行:
<RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
     xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

  <Description about="urn:mozilla:install-manifest">
    <em:id>extension@mozilla.org</em:id>
  </Description>
</RDF>

在我看来,这似乎是PHP的一个bug,因为如果我从XPath中删除属性,我总是会得到Description元素。但是我还不知道如何在XPath中使用命名空间,所以我在这里问。

1个回答

1
问题在于你第二个示例中的属性在空名称空间中。问题不是查询,而是你两个示例的 XML 数据并不等价。
请参见XML 1.0(第三版)中的命名空间

默认命名空间声明适用于其范围内的所有无前缀元素名称。默认命名空间声明不会直接适用于属性名称;未命名的属性的解释由它们所出现的元素决定。


好的,默认命名空间不直接应用于属性名称。我理解为没有前缀的属性获取与它们所在元素相同的命名空间,这样也没问题。但是,检查它们的命名空间,我可以看到它是_null_,因此这两个XML示例确实不相同。谢谢提示! - Sebastian Zartner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接