我正在尝试使用XML :: XPath从XML文档中提取内容。文档是使用命名空间指定的,但我想使用没有命名空间的XPath表达式。据我所知,我在两个不同的脚本中完成了这项工作。
在今天的某个时候,XML :: XPath的行为已经发生了变化。我没有看到我的改变使得这种行为发生了变化。
如果我几乎完全指定名称空间,在脚本中调用“set_namespace()”(硬编码我希望使用的前缀)并在XPath表达式中指定前缀,我可以使用一些手动测试。 / p>
同样,我很确定我昨天有这个工作,没有在脚本中调用“set_namespace()”,或者在XPath表达式中指定前缀。
如果我没有添加“set_namespace()”调用并在表达式中指定前缀,我只是从查询中获取空节点集。
我在创建第一个XPath对象之前尝试将“$ XML :: XPath :: Namespaces”设置为零,但这似乎没有任何区别。
以下是我将XML管道输入的简单脚本:
#! /bin/perl
use XML::XPath;
use XML::XPath::XMLParser;
use Getopt::Long;
$| = 1;
my $opt_file;
GetOptions("f|file=s" => \$opt_file);
$XML::XPath::Namespaces = 0;
my $xpath;
if ($opt_file ne '') {
$xpath = XML::XPath->new(filename => $opt_file);
}
else {
$xpath = XML::XPath->new(ioref => \*STDIN);
}
while (my $expr = shift @ARGV) {
my $nodeset = $xpath->find($expr);
if ($nodeset) {
if ($opt_file ne '') {
print $opt_file . ":\n";
}
my $node;
for $node ($nodeset->get_nodelist) {
print $node->string_value() . "\n";
}
}
}
这是一个示例命令行:
% echo "<ns3:abc xmlns:ns3=\"xxx\"><ns3:def>ghi</ns3:def></ns3:abc>" | xpathtext "//def"
我希望从中得到“ghi”,但我现在什么都没得到。
答案 0 :(得分:1)
让我们暂时忘记你的问题,暂时使用$XML::XPath::Namespaces=1;
(默认值)。
$ perl -E'say q{<r><e>E</e></r>}' |
xpathtext //e
E
正确。 null命名空间中有一个e
元素。
$ perl -E'say q{<r xmlns:p="http://n"><p:e>E</p:e></r>}' |
xpathtext //e
[nothing]
正确。 null命名空间中没有e
个元素。
$ perl -E'say q{<r xmlns="http://n"><e>E</e></r>}' |
xpathtext //e
E
不正确的。 null命名空间中没有e
个元素,但是打印了一个。
$ perl -E'say q{<r><e xmlns="http://n">E</e></r>}' |
xpathtext //e
E
不正确的。 null命名空间中没有e
个元素,但是打印了一个。
$ perl -E'say q{<r xmlns:p="http://n"><p:e>E</p:e></r>}' |
xpathtext //p:e
E
不正确的。这应该是一个错误,因为无法知道XPath中的p
是否指向http://n
命名空间。
$ perl -E'say q{<r xmlns="http://n"><e>E</e></r>}' |
xpathtext //p:e
[nothing]
不正确的。这应该是一个错误,因为无法知道XPath中的p
是否指向http://n
命名空间。
鉴于这种程度的懈怠,你遇到问题并不奇怪。
现在让我们找出$XML::XPath::Namespace=0;
的作用。
用$XML::XPath::Namespaces=0;
重新运行上述程序后,我们发现答案“绝对没有”。
我通过将魔法附加到变量来证实了这一点。永远不会使用该变量(在最新版本中,XML-XPath-1.13)!
所以模块一半做了你想要的,一半做了应有的事情,没有明显的定制方法。