Perl和XML :: Smart - 如何从XML文件中删除节点

时间:2013-01-07 01:19:05

标签: xml perl

我正在编写一个简单的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来完成这项任务,所以我希望这个问题可以在这个特定的库中解决。

2 个答案:

答案 0 :(得分:3)

虽然XML::Smart比基于它的XML::Simple更好,但在我看来,它仍然不是很擅长表示XML数据。在这种情况下,您必须知道要删除的节点是Perl数组的元素,并且在其上使用delete只需将元素设置为undef,同时将其保留到位(除非它碰巧是数组的最后一个元素。)

要操纵这样的数组,你需要splice,它可以正确地移除元素并向后移动元素以填充空间。使用

splice @{ $XML->{object} }, $n, 1

代替您的delete,您的代码应该适合您。

答案 1 :(得分:2)

永远不要在数组元素上使用existsdelete。也没有做任何有用的事情。

要从数组中删除元素,您需要向下移动所有其他元素。 splice可以做到这一点。

splice(@{ $XML->{object} }, $n, 1);

或者,如果它有助于您更好地理解,

splice(@{ $XML->{object} }, $n, 1, ());