我试图在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属性名称中的':',但我无法在查询中找到引用此属性的正确方法。任何帮助将不胜感激!
答案 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