包含命名空间前缀的属性的XPath查询

时间:2014-02-27 19:20:10

标签: xml perl xpath

我试图在Perl中使用XML :: XPath查询XML文档,但是当元素的属性名称包含名称空间前缀时,我遇到了问题。

示例XML:

<root xmlns="root-ns" xmlns:cat="urn:oasis:names:tc:entity:xmlns:xml:catalog"     xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="A" schematron-version="1.0" xsi:schemaLocation="some location">
  <elementA id="elementA">
    <ElementA-1>
      <ElementA-1-1 id="ElementA-1-1" xlink:href="#ElementA-1-1">
        <cat:catalog>
          <cat:uri name="name" uri="#something"/>
        </cat:catalog>
      </ElementA-1-1>
    </ElementA-1>
  </elementA>
</root>

我的查找查询如下所示:

if ($nodeset = $nodes->find("/root/elementA[\@id='elementA']/ElementA-1/ElementA-1-1[\@xlink:href='#ElementA-1-1']/cat:catalog/cat:uri/\@uri") {
  print "nodeset found.\n";
}
else {
  print "no nodeset found.\n";
}

当我针对示例XML文档运行此操作时,XPath会抱怨@xlink:href属性名称中的':',但我无法在查询中找到引用此属性的正确方法。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您的问题中的Perl代码无法编译,因为括号不匹配。

如果我解决了这个问题并交换单引号和双引号(这样就不需要转义),那么你的XPath表达式就可以正常工作。

请注意,您有一个非常具体的XPath字符串,并且很少需要对您感兴趣的节点的路径内容非常明确。只需//cat:uri/@uri即可完成此任务。

use strict;
use warnings;

use XML::XPath;

my $xp = XML::XPath->new(xml => <<'END');
<root xmlns="root-ns" xmlns:cat="urn:oasis:names:tc:entity:xmlns:xml:catalog"     xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="A" schematron-version="1.0" xsi:schemaLocation="some location">
  <elementA id="elementA">
    <ElementA-1>
      <ElementA-1-1 id="ElementA-1-1" xlink:href="#ElementA-1-1">
        <cat:catalog>
          <cat:uri name="name" uri="#something"/>
        </cat:catalog>
      </ElementA-1-1>
    </ElementA-1>
  </elementA>
</root>
END


my $nodeset = $xp->find('/root/elementA[@id="elementA"]/ElementA-1/ElementA-1-1[@xlink:href="#ElementA-1-1"]/cat:catalog/cat:uri/@uri');

for my $node ($nodeset->get_nodelist) {
  printf "Name:  %s\n",  $node->getName;
  printf "Value: %s\n",  $node->getValue;
}

<强>输出

Name:  uri
Value: #something