我有如下的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.
我该如何解决这个问题?当我们发现有时节点不在那里时,存储这些数据的最佳数据结构是什么?
答案 0 :(得分: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是否为空。