I've tried several different methods for parsing XML documents. I need to find a node in the document with an x
attribute, and then move that node with its children to a different parent node.
I've had some success using XML::LibXML
for locating the node and being able to iterate through it's children, but I'm stuck in how to move it to a different parent.
Using $node->cloneNode(1)
looks promising but I can't find good examples of its use.
This is the original XML data
<config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
<old>
<server name="sahara" osname="solaris" osversion="2.6">
<address ip="10.0.0.101">Private</address>
<address ip="10.0.1.101">Private</address>
</server>
<server name="gobi" osname="irix" osversion="6.5">
<address ip="10.0.0.102">Private</address>
</server>
<server name="kalahari" osname="linux" osversion="2.0.34">
<address ip="10.0.0.103">Private</address>
<address ip="10.0.1.103">Private</address>
</server>
</old>
<new>
</new>
</config>
and this is the result I would like
<config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
<old>
<server name="sahara" osname="solaris" osversion="2.6">
<address ip="10.0.0.101">Private</address>
<address ip="10.0.1.101">Private</address>
</server>
<server name="gobi" osname="irix" osversion="6.5">
<address ip="10.0.0.102">Private</address>
</server>
</old>
<new>
<server name="kalahari" osname="linux" osversion="2.0.34">
<address ip="10.0.0.103">Private</address>
<address ip="10.0.1.103">Private</address>
</server>
</new>
</config>
Using XML::LibXML
:
use strict;
use warnings;
use XML::LibXML;
my $xml = XML::LibXML->load_xml( IO => \*DATA );
my ($new) = $xml->findnodes('//new');
for my $linux ( $xml->findnodes('//old/server[@osname="linux"]') ) {
$linux->unbindNode(); # Remove from Parent (done automatically when added elsewhere without cloning)
$new->addChild($linux);
}
print $xml;
__DATA__
<config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
<old>
<server name="sahara" osname="solaris" osversion="2.6">
<address ip="10.0.0.101">Private</address>
<address ip="10.0.1.101">Private</address>
</server>
<server name="gobi" osname="irix" osversion="6.5">
<address ip="10.0.0.102">Private</address>
</server>
<server name="kalahari" osname="linux" osversion="2.0.34">
<address ip="10.0.0.103">Private</address>
<address ip="10.0.1.103">Private</address>
</server>
</old>
<new>
</new>
</config>
Outputs:
<?xml version="1.0"?>
<config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
<old>
<server name="sahara" osname="solaris" osversion="2.6">
<address ip="10.0.0.101">Private</address>
<address ip="10.0.1.101">Private</address>
</server>
<server name="gobi" osname="irix" osversion="6.5">
<address ip="10.0.0.102">Private</address>
</server>
</old>
<new>
<server name="kalahari" osname="linux" osversion="2.0.34">
<address ip="10.0.0.103">Private</address>
<address ip="10.0.1.103">Private</address>
</server></new>
</config>