我有以下XML:
<config>
<version general="1.2.3">
<subtype type="a" version="1.2" />
<subtype type="b" version="3.6" />
...
</version>
...
</config>
我在Perl中有一些代码可以从数据库中获取配置节点。
获得后,如果我尝试以下内容:
my $elem = $cfg->getElementsByTagName("version");
my $generalVer = $elem ? $elem->get_node(1)->getAttribute("general") : undef;
一切正常,$generalVer
包含1.2.3
,正如所料。
但如果我试试这个:
my $elem = $cfg->getElementsByTagName("version/subtype[@type='a']");
my $aVersion = $elem ? $elem->get_node(1)->getAttribute("version") : undef;
它失败并显示“无效谓词”消息。
有人可以帮忙解决这个问题吗?
答案 0 :(得分:9)
我强烈怀疑"version/subtype[@type='a']"
实际上不是标签名称。这看起来像是一个XPath查询。
我假设您正在使用XML::DOM之类的东西来解析此XML。如果要使用XPath,则可以使用XML::DOM::XPath,这会增加XPath支持。
例如,
use XML::DOM;
use XML::DOM::XPath;
...
my $elem = $cfg->findnodes( q{//version/subtype[@type='a']} );
答案 1 :(得分:5)
感谢大家的答案。
在我提出问题后的短时间内,有人回答说问题是单引号,如果我使用双引号就可以了。即@type=
“ a
”而不是@type=
' a
“强>
嗯,这确实解决了它。但当我试图将他的答案标记为正确答案时,我发现他删除了答案。
所以我自己发布了答案,只是为了记录。
以下代码可以正常使用:
my $elem = $cfg->getElementsByTagName("version/subtype[@type=\"a\"]");
my $aVersion = $elem ? $elem->get_node(1)->getAttribute("version") : undef;
感谢。
答案 2 :(得分:4)
getElementsByTagName
方法需要一个名称,我认为它不支持XPath。要使用XPath查询,您必须使用XML :: XPath之类的模块,而不是XML :: DOM。
以下是使用XML :: XPath的示例:
#!/usr/bin/perl
use strict;
use warnings;
use XML::XPath;
my $xml = <<END;
<config>
<version general="1.2.3">
<subtype type="a" version="1.2" />
<subtype type="b" version="3.6" />
</version>
</config>
END
my $xp = XML::XPath->new(xml => $xml);
my $nodeset = $xp->find("//version/subtype[\@type='a']");
foreach my $node ($nodeset->get_nodelist) {
my $version = $node->getAttribute("version");
print "Version: $version\n";
}
请注意,您必须转义@
中的subtype[\@type='a'
,否则Perl将会查找名为@type
的数组。
答案 3 :(得分:1)
您必须使用XPath通过路径选择元素,或者分两步执行。 getElementsByTagName()只能处理标记名称 - 而不能处理元素的路径。当你进行条件选择时,首选XPath(你使用“@ type ='a'”)。