为什么我从getElementsByTagName获得“无效谓词”错误?

时间:2009-12-27 12:49:22

标签: xml perl

我有以下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;

它失败并显示“无效谓词”消息。

有人可以帮忙解决这个问题吗?

4 个答案:

答案 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'”)。