【问题标题】:XML::Twig concatenate XML files but keep the outer nodesXML::Twig 连接 XML 文件但保留外部节点
【发布时间】:2018-04-24 04:20:45
【问题描述】:

我正在尝试将两个 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>

【问题讨论】:

  • 您的“预期输出”不是有效的 XML。
  • 那些只是模型。我不想发布我正在使用的大型 XML 文件。
  • 所以我们应该猜测“你的真正需求?
  • 当我看到您需要完美时,我已经编辑了预期的输出。
  • 谢谢。这不仅仅是一种“完美的需求”:绝对的准确性在编程中是必不可少的,而马虎是许多错误和问题的原因。我还对您的 XML 进行了适当的缩进,以便于理解。

标签: xml perl xml-twig


【解决方案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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2016-11-20
    • 1970-01-01
    相关资源
    最近更新 更多