我试图选择一个使用XPath查询的节点,我不明白为什么XML :: LibXML在找不到节点时找不到节点它有一个xmlns属性。这里有一个脚本来演示该问题:为什么在使用命名空间时XML :: LibXML找不到这个xpath查询的节点
#!/usr/bin/perl
use XML::LibXML; # 1.70 on libxml2 from libxml2-dev 2.6.16-7sarge1 (don't ask)
use XML::XPath; # 1.13
use strict;
use warnings;
use v5.8.4; # don't ask
my ($xpath, $libxml, $use_namespace) = @ARGV;
my $xml = sprintf(<<'END_XML', ($use_namespace ? 'xmlns="http://www.w3.org/2000/xmlns/"' : q{}));
<?xml version="1.0" encoding="iso-8859-1"?>
<RootElement>
<MyContainer %s>
<MyField>
<Name>ID</Name>
<Value>12345</Value>
</MyField>
<MyField>
<Name>Name</Name>
<Value>Ben</Value>
</MyField>
</MyContainer>
</RootElement>
END_XML
my $xml_parser
= $libxml ? XML::LibXML->load_xml(string => $xml, keep_blanks => 1)
: XML::XPath->new(xml => $xml);
my $nodecount = 0;
foreach my $node ($xml_parser->findnodes($xpath)) {
$nodecount ++;
print "--NODE $nodecount--\n"; #would use say on newer perl
print $node->toString($libxml && 1), "\n";
}
unless ($nodecount) {
print "NO NODES FOUND\n";
}
该脚本可以让你的XML ::的libxml解析器和XML :: XPath的解析器之间进行选择。它还允许您在MyContainer元素上定义xmlns属性或根据传递的参数将其关闭。
我使用的xpath表达式是“RootElement/MyContainer”。当我使用XML ::的libxml解析器没有命名空间运行查询发现该节点没有问题:
[email protected]:~$ ROC/ECG/libxml_xpath.pl 'RootElement/MyContainer' libxml
--NODE 1--
<MyContainer>
<MyField>
<Name>ID</Name>
<Value>12345</Value>
</MyField>
<MyField>
<Name>Name</Name>
<Value>Ben</Value>
</MyField>
</MyContainer>
然而,当我在的地方与命名空间中运行它发现没有节点:
[email protected]:~$ ROC/ECG/libxml_xpath.pl 'RootElement/MyContainer' libxml use_namespace
NO NODES FOUND
对比这与使用XMLL :: XPath的解析器,当输出:
[email protected]:~$ ROC/ECG/libxml_xpath.pl 'RootElement/MyContainer' 0 # no namespace
--NODE 1--
<MyContainer>
<MyField>
<Name>ID</Name>
<Value>12345</Value>
</MyField>
<MyField>
<Name>Name</Name>
<Value>Ben</Value>
</MyField>
</MyContainer>
[email protected]:~$ ROC/ECG/libxml_xpath.pl 'RootElement/MyContainer' 0 1 # with namespace
--NODE 1--
<MyContainer xmlns="http://www.w3.org/2000/xmlns/">
<MyField>
<Name>ID</Name>
<Value>12345</Value>
</MyField>
<MyField>
<Name>Name</Name>
<Value>Ben</Value>
</MyField>
</MyContainer>
以下哪个解析器实现的是做什么的“权利”?为什么XML :: LibXML在使用命名空间时对它的处理方式不同?当命名空间到位时,我能做些什么来检索节点?
好问题,+1。请参阅我的回答以获得解释和两种可能的解决方案 – 2010-11-03 03:07:23
@ikegami,因此必须对高级*和*新手用户都有用。他们不应该气馁地提问。 – 2014-03-27 14:32:56