Perl Hash使用LibXML

问题描述 投票:0回答:1

我有一个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在散列中插入空格作为值(我打印了此散列并发现只有空格打印为值)。

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

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

我该如何解决这个问题?当我们发现有时某个节点不在那里时,存储这些数据的最佳数据结构是什么?

perl libxml2
1个回答
4
投票

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

使用my $value = $node->getChildrenByTagName('data2');$value将始终是NodeList对象。它可能是一个空的NodeList,但你总是得到一个NodeList对象。


您的XML :: LibXML版本已过期。您的XML :: LibXML :: NodeList版本没有字符串比较重载,默认情况下,Perl不会“回退”为其他字符串运算符(如ne)使用字符串化。 I reported this bug back in 2010,它是fixed in 2011 in version 1.77

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

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

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

但实际上,更新该模块。已经做了很多工作。

Perl在散列中插入空格作为值

这是一个NodeList对象字符串化。我从一个空的NodeList中得到一个空字符串。你可能会得到一个空间作为一个旧的bug。

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

© www.soinside.com 2019 - 2024. All rights reserved.