XML :: Twig连接XML文件但保留外部节点

时间:2017-11-10 21:14:20

标签: xml perl xml-twig

我正在尝试将两个XML文件连接在一起但保留外部节点。下面是我发现的一个例子,但是因为它定义了一个根节点,所以其他节点都被丢弃了。

我尝试使用twig_print_outside_roots => 1,但这不起作用。我尝试了其他方法,但似乎比例子更远,所以经过几个小时的尝试后我才能伸出手。

非常感谢任何帮助。我更喜欢使用XML::Twig,因为我已经使用它来执行其他与XML相关的任务。

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $result_twig;

foreach my $file ( 'to_concat_1.xml', 'to_concat_2.xml' ) {

    my $current_twig = XML::Twig->new( twig_roots => { Content => 1 } )->parsefile( $file );

    if ( ! $result_twig ) {
        $result_twig = $current_twig;
    }
    else {
        $current_twig->root->move( last_child => $result_twig->root )->erase;
    }
}

$result_twig->print;

to_concat_1.xml

<Envelope>
  <Body>
    <ContentRS>
      <Success/>
      <Contents>
        <Content>
          <Name> Mike </Name>
          <Email> mike@somewhere.com</Email>
        </Content>
      </Contents>
    </ContentRS>
  </Body>
</Envelope>

to_concat_2.xml

<Envelope>
  <Body>
    <ContentRS>
      <Success/>
      <Contents>
        <Content>
          <Name> Mark </Name>
          <Email> mark@somewhere.com</Email>
        </Content>
      </Contents>
    </ContentRS>
  </Body>
</Envelope>

输出:

<Envelope>
  <Content>
    <Name> Mike </Name>
    <Email> mike@somewhere.com</Email>
  </Content>
  <Content>
    <Name> Mark </Name>
    <Email> mark@somewhere.com</Email>
  </Content>
</Envelope>

预期产出:

<Envelope>
  <Body>
    <ContentRS>
      <Success/>
      <Contents>
        <Content>
          <Name> Mike </Name>
          <Email> mike@somewhere.com</Email>
        </Content>
        <Content>
          <Name> Mark </Name>
          <Email> mark@somewhere.com</Email>
        </Content>
      </Contents>
    </ContentRS>
  </Body>
</Envelope>

1 个答案:

答案 0 :(得分:1)

我明白了,所以我发布了我想出来的东西,以防它帮助其他人。

use strict;
use warnings;

use XML::Twig;

my @files = ( 'file1.xml', 'file2.xml', 'file3.xml' );

my $masterFile = pop( @files );

my @content;

foreach my $file ( @files ) {

    XML::Twig->new(
        twig_handlers => {
            'Content' => sub { push @content, $_; $_->cut(); }
        }
    )->parsefile( $file );
}

my $twig = XML::Twig->new(
    pretty_print  => 'indented_a',
    twig_handlers => {
        'Contents' => sub {
            foreach my $content ( @content ) {
                $content->paste( last_child => $_ );
            }
        }
    }
)->parsefile( $masterFile );

$twig->print;