如何在perl中使用XML :: Simple从XML中删除节点

use*_*361 0 xml perl

我需要使用XML :: Simple从xml中删除一个节点

我的XML看起来像:

<Install>
<version >
<number>6.0</number>
<build>1014445</build>
<path>path</path>
<kind>native</kind>
</version>
<version >
<number>6.1</number>
<build>1025654</build>
<path>path</path>
<kind>native</kind>
</version>
</Install>
Run Code Online (Sandbox Code Playgroud)

我需要在版本下删除与特定号码匹配的节点,比如我需要删除number = 6.0的节点.更新的XML将如下所示: -

<Install>
<version >
<number>6.1</number>
<build>1025654</build>
<path>path</path>
<kind>native</kind>
</version>
</Install>
Run Code Online (Sandbox Code Playgroud)

请原谅我,如果这个问题重复,我是perl的新手.

Bor*_*din 6

这是一个使用的解决方案XML::Twig.正如我在我的评论说,该XML::Simple模块是不是一个好的选择,除非你没有选择

XML::Twig使用XPath的子集,因此用于查找所需version元素的表达式与XML::LibXML解决方案中的表达式不同

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig->new;
$twig->parsefile('install.xml');

for my $number ( $twig->findnodes('/Install/version/number[string()="6.0"]') ) {
    $number->parent->delete;
}

$twig->set_pretty_print('indented_c');
$twig->print;
Run Code Online (Sandbox Code Playgroud)

产量

<Install>
  <version>
    <number>6.1</number>
    <build>1025654</build>
    <path>path</path>
    <kind>native</kind>
  </version>
</Install>
Run Code Online (Sandbox Code Playgroud)

更新

如果要使程序直接写入新的XML文件而不是使用命令行重定向输出,那么只需要open新文件并将文件句柄传递给print方法调用

像这样

open my $xml_fh, '>', 'install_new.xml' or die $!;
$twig->set_pretty_print('indented_c');
$twig->print($xml_fh);
Run Code Online (Sandbox Code Playgroud)

更新2

要将要删除的版本号指定为变量,可以将字符串的值插入到XPath表达式中

my $filter = '6.0';

for my $number ( $twig->findnodes(qq{/Install/version/number[string()="$filter"]} } {
    ...
}
Run Code Online (Sandbox Code Playgroud)

但最好迭代所有number元素并编写显式比较,如下所示

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig->new;
$twig->parsefile('install.xml');

my $filter = '6.0';

for my $number ( $twig->findnodes('/Install/version/number') ) {
  $number->parent->delete if $number->trimmed_text eq $filter;
}

$twig->set_pretty_print('indented_c');
$twig->print;
Run Code Online (Sandbox Code Playgroud)


ike*_*ami 5

几乎不可能让 XML::Simple 产生与读入的相同的输出。出于这个原因和其他原因,该模块的文档指出

不鼓励在新代码中使用此模块

我会使用 XML::LibXML。

$_->unbindNode() for $doc->findnodes( '/Install/version[number="6.0"]' );
Run Code Online (Sandbox Code Playgroud)