5

我正在编写一个简单的 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->data(); 的各种排列;但没有一个工作。我更愿意继续使用 XML::Smart 来完成这个任务,所以我希望这个问题可以在这个特定的库中得到解决。

4

2 回答 2

3

While XML::Smart is way better than XML::Simple, on which it is based, in my opinion it is still really not very good at representing XML data. In this case you have to be aware that the node you want to delete is an element of a Perl array, and using delete on it will simply set the element to undef while leaving it in place (unless it happens to be the last element of the array).

To manipulate arrays like this you need splice, which correctly removes elements and moves later ones down to fill the space. Use

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

instead of your delete and your code should work for you.

于 2013-01-07T02:19:27.710 回答
2

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

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

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

或者,如果它可以帮助您更好地理解,

splice(@{ $XML->{object} }, $n, 1, ());
于 2013-01-07T01:30:18.147 回答