使用 LibXML 的 Perl 哈希

Perl Hash using LibXML

我有一个XML数据如下。

<type>
   <data1>something1</data1>
   <data2>something2</data2>
</type>
<type>
   <data1>something1</data1>
   <data2>something2</data2>
</type>
<type>
   <data1>something1</data1>
</type>

可以看出,子节点data2有时不存在。

我使用 this 作为创建以下代码的指南。

my %hash;
my $parser = XML::LibXML->new();
my $doc    = $parser->parse_file($file_name);
my @nodes  = $doc->findnodes("/type");

foreach my $node(@nodes)
{
    my $key = $node->getChildrenByTagName('data1');
    my $value = $node->getChildrenByTagName('data2');
    $hash{$key} = $value;
}

稍后,如果子节点 data2 存在与否,我将使用此散列根据事实生成更多数据。

我使用 ne 运算符假设 %hash 中的数据是字符串的键值对,并且当 data2 不存在时,Perl 将 space 作为值插入在散列中(我已经打印了这个散列,发现只有 space 被打印为一个值)。

但是,我最终遇到了以下编译错误。

Operation "ne": no method found,
        left argument in overloaded package XML::LibXML::NodeList,
        right argument has no overloaded magic at filename.pl line 74.

我该如何解决这个问题?当我们看到有时节点不存在时,存储此数据的最佳数据结构是什么?

首先要意识到 $value 是一个 XML::LibXML::NodeList 对象。当你打印它时,它看起来只是一个字符串,因为它有超载的字符串化。您可以使用 ref $value.

查看

对于 my $value = $node->getChildrenByTagName('data2');$value总是 是一个 NodeList 对象。它可能是一个空的 NodeList,但您总是会得到一个 NodeList 对象。


您的 XML::LibXML 版本已过时。您的 XML::LibXML::NodeList 版本没有字符串比较重载,默认情况下,Perl 不会 "fallback" 对其他字符串运算符(例如 ne)使用字符串化。 I reported this bug back in 2010 and it was fixed in 2011 in version 1.77.

升级XML::LibXML,问题就会消失。

作为解决方法,您可以通过引用 NodeList 对象来强制进行字符串化。

if( "$nodelist" ne "foo" ) { ... }

但是真的,更新那个模块。已经为此做了很多工作。

Perl inserts space as a value in the hash

这是一个 NodeList 对象字符串化。我从一个空的 NodeList 中得到一个空字符串。您可能会收到 space 作为旧错误。

您还可以检查 $value->size 以查看 NodeList 是否为空。