【问题标题】:How to add node to a XML file using perl XML::Twig如何使用 perl XML::Twig 将节点添加到 XML 文件
【发布时间】:2015-07-24 23:28:46
【问题描述】:

我需要将一个节点添加到一个已经存在的 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

我需要添加节点并将更改保存到文件中。 它应该反映在文件中。 我是 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>

【问题讨论】:

  • 请展示您已经尝试过的内容。 Edit您的问题并在您链接的答案的帮助下输入您编写的代码。看起来答案应该适合你。
  • @simbabque 我已经编辑了添加我的代码的问题。
  • 您的$myXML 不正确。将您给出的预期输出与您所做的进行比较。元素嵌套不正确。
  • @simbabque 我已经更新了 $myXML 但没有更新到 xml 文件。

标签: xml perl


【解决方案1】:

虽然代码 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>
...

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

您从答案中获取的代码应该适用于元素&lt;grouping&gt;。原则上它是相同的,但它有不同的名称。所以你需要调整代码。我将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>

【讨论】:

  • 谢谢,有没有办法在 $myXML 中使用变量??
  • 如果你使用双引号,它会插入变量。如果这对你来说是新的,我建议你买一些 perl 书。标签 wiki 有一个很好的免费资源和书籍推荐列表:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
相关资源
最近更新 更多