Reputation: 73
I'm trying to concatenate two XML files together but keep the outer nodes. Below is an example I found which does this but because it works off defining a root node the other nodes are discarded.
I tried using twig_print_outside_roots => 1
but this does not work. I have tried other approaches but seem to get further away than the example so after hours of trying I'm reaching out.
Any help is much appreciated. I prefer to use XML::Twig
because I'm already using it to do other XML-related tasks.
#!/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;
<Envelope>
<Body>
<ContentRS>
<Success/>
<Contents>
<Content>
<Name> Mike </Name>
<Email> [email protected]</Email>
</Content>
</Contents>
</ContentRS>
</Body>
</Envelope>
<Envelope>
<Body>
<ContentRS>
<Success/>
<Contents>
<Content>
<Name> Mark </Name>
<Email> [email protected]</Email>
</Content>
</Contents>
</ContentRS>
</Body>
</Envelope>
<Envelope>
<Content>
<Name> Mike </Name>
<Email> [email protected]</Email>
</Content>
<Content>
<Name> Mark </Name>
<Email> [email protected]</Email>
</Content>
</Envelope>
Expected Output:
<Envelope>
<Body>
<ContentRS>
<Success/>
<Contents>
<Content>
<Name> Mike </Name>
<Email> [email protected]</Email>
</Content>
<Content>
<Name> Mark </Name>
<Email> [email protected]</Email>
</Content>
</Contents>
</ContentRS>
</Body>
</Envelope>
Upvotes: 1
Views: 184
Reputation: 73
I figured it out, so I'm posting what I came up with in case it helps someone else.
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;
Upvotes: 1