xml - 如何使用 perl XML::Twig 将节点添加到 XML 文件

标签 xml perl

我需要向已有的 xml 文件添加一个节点,我的 xml 如下:-

<Install>
  <version >
    <number>6.1</number>
    <build>1025654</build>
    <path>path</path>
    <kind>RIBS</kind>
  </version>
</Install>

添加节点后,它应该看起来像

<Install>
  <version >
    <number>6.1</number>
    <build>1025654</build>
    <path>path</path>
    <kind>native</kind>
  </version>
  <version >
    <number>6.0</number>
    <build>1025786</build>
    <path>path</path>
    <kind>native</kind>
  </version>
</Install>

我尝试了以下链接中的想法,但无法弄清楚。 using perl insert string xml to a node

我需要添加节点并将更改保存到文件中。 它应该反射(reflect)到文件中。 我是 Perl 新手,为什么无法弄清楚。

我尝试的是:-

use strict;
use warnings;

use XML::Twig;

my $myXML
  ='<version>6.1</version>
    <number>101445</number>
    <path>path</path>
    <kind>native</kind>
   ';
my $file = "C:\\Users\\bjoshi\\LightroomBuilds\\Win\\data.xml";
my $t= XML::Twig->new( twig_handlers => { grouping => sub { grouping( $myXML, @_); }, })
                ->parsefile( "$file") or die $!;

$t->print;
open my $xml_fh, '>', "$file" or die $!;
$t->set_pretty_print('indented_c');
$t->print($xml_fh);
exit;

sub grouping
  { my( $xml, $t, $grouping)= @_;
    my $new_elt= XML::Twig::Elt->parse( $xml);
    $new_elt->paste( last_child => $grouping);
  }

我得到的输出是:-

<Install>
  <version>
    <number>6.1</number>
    <build>1025654</build>
    <path>path</path>
    <kind>native</kind>
  </version>
</Install>

最佳答案

而代码from the linked answer by mirod做了与您想做的相同的事情,您需要调整它以适合您的 XML。我将在下面解释我做了什么。

use strict;
use warnings;
use XML::Twig;

my $myXML = <<'XML';
<version>
  <number>6.0</number>
  <build>1025786</build>
  <path>path</path>
  <kind>native</kind>
</version>
XML

my $t = XML::Twig->new(
  twig_handlers => {
    Install => sub { add_version( $myXML, @_ ); }, }
  )->parse( \*DATA ) or die $!;

$t->set_pretty_print('indented_c');
$t->print;

sub add_version {
    my ( $xml, $t, $install ) = @_;
    my $new_elt = XML::Twig::Elt->parse($xml);
    $new_elt->paste( last_child => $install );
}

__DATA__
<Install>
  <version >
    <number>6.1</number>
    <build>1025654</build>
    <path>path</path>
    <kind>RIBS</kind>
  </version>
</Install>

这不会从文件中读取,而是从 DATA 中读取。获取以下内容的文件句柄 __DATA__ ,然后打印到终端/屏幕。

首先,您的预期输出是这样的:

<Install>
  ...
  <version>
    <number>6.0</number>
    ...
  </version>
</Install>

但是您在代码中使用的要插入的 XML 片段如下所示:

<version>6.1</version>
<number>101445</number>
...

这不是你所说的你想要的,所以我想这是一个错误。

您从答案中获取的代码应该适用于元素 <grouping> 。原则上是相同的,但名称不同。所以你需要调整代码。我改变了twig_handlers拥有 Install 的处理程序因为那是 XML 的根元素。我继续重命名子例程和内部变量以匹配它。它使发生的事情更加清楚。

如果运行它,您会得到以下输出:

<Install>
  <version>
    <number>6.1</number>
    <build>1025654</build>
    <path>path</path>
    <kind>RIBS</kind>
  </version>
  <version>
    <number>6.0</number>
    <build>1025786</build>
    <path>path</path>
    <kind>native</kind>
  </version>
</Install>

关于xml - 如何使用 perl XML::Twig 将节点添加到 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31611332/

相关文章:

javascript - 客户端 XSLT 转换其他人的 XML

perl - 如何有条件地定义 Perl 子程序?

perl - 在双引号内打印数组

android - 为什么列表首选项中的条目没有显示在应用程序中?

java - 强制 jaxb 解码器忽略 html 标签

c# - 将 XML 反序列化为类

perl - perl 中的自定义数组排序

linux - 使用 sudo 作为另一个用户运行时的 Perl 系统调用

regex - 如何使用grep/sed打印文件,不包括注释和空白行?

php - 使用 SimpleXML 加载远程 URL