我正在编写一个简单的Perl脚本,它使用XML :: Smart来创建和解析XML文件。我遇到了删除XML节点的问题。我有以下代码:
if ( exists $XML->{object}[$n] ) {
delete $XML->{object}[$n] ;
};
$XML->save('dane.xml') ;
它做了预期的事情 - 即删除了正确的节点。但是,当我稍后尝试列出所有节点(特定根的子节点)时,使用下面的代码(通常可以正常工作):
my @objects = $XML->{object}('@') ;
foreach my $object (@objects) {
say "$object->{address}";
};
Perl列出所有节点,直到删除之前的节点,然后吐出以下错误:
Not a HASH reference at g:/Dwimperl/perl/site/lib/XML/Smart/Tie.pm line 48, <STDIN> line 2.
我很难过 - 我尝试使用$ XML-&gt; data()的各种排列方式;但都没有用。我更愿意继续使用XML :: Smart来完成这项任务,所以我希望这个问题可以在这个特定的库中解决。
答案 0 :(得分:3)
虽然XML::Smart
比基于它的XML::Simple
更好,但在我看来,它仍然不是很擅长表示XML数据。在这种情况下,您必须知道要删除的节点是Perl数组的元素,并且在其上使用delete
只需将元素设置为undef
,同时将其保留到位(除非它碰巧是数组的最后一个元素。)
要操纵这样的数组,你需要splice
,它可以正确地移除元素并向后移动元素以填充空间。使用
splice @{ $XML->{object} }, $n, 1
代替您的delete
,您的代码应该适合您。
答案 1 :(得分:2)
永远不要在数组元素上使用exists
和delete
。也没有做任何有用的事情。
要从数组中删除元素,您需要向下移动所有其他元素。 splice
可以做到这一点。
splice(@{ $XML->{object} }, $n, 1);
或者,如果它有助于您更好地理解,
splice(@{ $XML->{object} }, $n, 1, ());