如果元素具有 xmlns 属性,Xpath 将失败 [重复]

Posted

技术标签:

【中文标题】如果元素具有 xmlns 属性,Xpath 将失败 [重复]【英文标题】:Xpath fails if an element has a a xmlns attribute [duplicate] 【发布时间】:2011-07-14 05:20:15 【问题描述】:

可能重复:xPath finds nothing but *

我正在尝试使用 xml 来解析 .COLLADA 文件。问题是如果根标记具有 xmlns 属性,我似乎无法使用 xpath() 访问元素。

例如这有效:

$string = <<<TEST
<?xml version="1.0" encoding="utf-8"?>
<COLLADA version="1.4.1">
  <library_materials>
    <material id="Material" name="Material">
      <instance_effect url="#Material-effect"/>
    </material>
    <material id="Material2" name="Material">
      <instance_effect url="#Material-effect2"/>
    </material>
  </library_materials>
</COLLADA>
TEST;
$lol = new SimpleXMLElement($string);
print_r($lol->library_materials->xpath("material[@id='Material2']"));

但这不是:

$string = <<<TEST
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
  <library_materials>
    <material id="Material" name="Material">
      <instance_effect url="#Material-effect"/>
    </material>
    <material id="Material2" name="Material">
      <instance_effect url="#Material-effect2"/>
    </material>
  </library_materials>
</COLLADA>
TEST;
$lol = new SimpleXMLElement($string);
print_r($lol->library_materials->xpath("material[@id='Material2']"));

xmlns 是如何突然使 xml 树无法使用的?我认为它只是定义了名称空间,因此您可以将它与其他名称空间中的其他相同标签区分开来。我错过了什么?

【问题讨论】:

【参考方案1】:

你需要注册命名空间:

$lol = new SimpleXMLElement($string);
$lol->registerXPathNamespace('cada', 'http://www.collada.org/2005/11/COLLADASchema');
print_r($lol->xpath("child::cada:library_materials//*[@id='Material2']"));

【讨论】:

谢谢!我确实通过在所有查询中输入 *[namespace-uri()='collada.org/2005/11/COLLADASchema' 和 ORIGINALEXPRESSION] 自己解决了这个问题,但这是一个更优雅的解决方案。【参考方案2】:

名称空间声明意味着名称位于名称空间中,但您的 XPath 正在寻找没有名称空间中的名称。搜索命名空间元素的方式取决于您使用的是 XPath 1.0 还是 2.0,并且就您在 XPath 中使用命名空间前缀来表示命名空间名称而言,声明前缀的方式取决于 XPath 处理器的 API你正在使用。

【讨论】:

以上是关于如果元素具有 xmlns 属性,Xpath 将失败 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

XPath:选择具有显式“xmlns”属性的节点

具有特定值的任何属性的所有元素的 XPath?

Xpath - 选择具有属性的元素并获取另一个属性值

Xpath 获取具有至少一个属性的所有元素

Xpath:选择除具有特定属性的元素之外的所有元素

xpath按元素和属性查找节点,其中包含具有特定id的子元素