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

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 完成这项任务,所以希望能够在这个特定的库中解决这个问题。


+1 我同意 slm 的观点 - 这篇文章写得非常清晰易懂 - Borodin
2个回答

3
XML::Smart虽然比其基础库XML::Simple好得多,但在我的看法中,它仍然不太适合表示XML数据。在这种情况下,您需要注意您要删除的节点是Perl数组的一个元素,使用delete只会将其设置为undef并保留在原地(除非它恰好是数组的最后一个元素)。
要像这样操作数组,您需要使用splice,它可以正确地删除元素并将后面的元素下移以填补空间。使用:
splice @{ $XML->{object} }, $n, 1

你需要使用 remove 代替 delete,这样你的代码才能正常工作。


2

永远不要在数组元素上使用existsdelete,它们都没有任何有用的作用。

如果想要删除数组中的元素,需要将其他元素下移。可以使用splice来实现。

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

或者如果它有助于您更好地理解,
splice(@{ $XML->{object} }, $n, 1, ());

太棒了 - 它运行了!我想我对Perl数组的确切理解有些错误 - 但这完美地澄清了它。非常感谢! - marmarta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接