jacksparrow007
jacksparrow007

Reputation: 1328

Merge two xml files using perl

I have two xml files of the type

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="whatever">
    <types>
        <members>test1</members>
        <name>test2</name>
    </types>
    <types>
        <members>test3</members>
        <name>test4</name>
    </types>
    <version>25.0</version>
</Package>

and

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="whatever">
    <types>
        <members>test5</members>
        <name>test6</name>
    </types>
    <version>25.0</version>
</Package>

I want to concatenate these two using perl to produce the result

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Package xmlns="whatever">
        <types>
            <members>test1</members>
            <name>test2</name>
        </types>
        <types>
            <members>test3</members>
            <name>test4</name>
        </types>
        <types>
            <members>test5</members>
            <name>test6</name>
        </types>
        <version>25.0</version>
    </Package>

How can I do this using Perl?

Upvotes: 0

Views: 2607

Answers (2)

Jean
Jean

Reputation: 22705

I would start at XML::Merge from CPAN

Upvotes: 0

Slaven Rezic
Slaven Rezic

Reputation: 4581

Here's a solution with XML::LibXML. Basically it calls the insertBefore method to copy a node from the 2nd document to the 1st document. Tweak the script as you like, e.g. to do things differently if same nodes are found in both packages.

use strict;
use XML::LibXML;

my $xml1 = <<'EOF';
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="whatever">
    <types>
        <members>test1</members>
        <name>test2</name>
    </types>
    <types>
        <members>test3</members>
        <name>test4</name>
    </types>
    <version>25.0</version>
</Package>
EOF

my $xml2 = <<'EOF';
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="whatever">
    <types>
        <members>test5</members>
        <name>test6</name>
    </types>
    <version>25.0</version>
</Package>
EOF

my $doc1 = XML::LibXML->new->parse_string($xml1);
my $doc2 = XML::LibXML->new->parse_string($xml2);

my($version_node) = $doc1->findnodes('//*[local-name()="version"]');
die if !$version_node;

for my $types_node ($doc2->findnodes('//*[local-name()="types"]')) {
    $version_node->parentNode->insertBefore($types_node, $version_node);
}

print $doc1->serialize;

Upvotes: 2

Related Questions