tcdaly
tcdaly

Reputation: 35

Add new nodes to a set of existing nodes (Perl XML::LibXML)

Using the Perl XML::LibXML library, I'm trying to add a new node to each of a set of existing nodes in an XML document, using a loop. This is my attempt so far:

#!/usr/bin/perl -w
use 5.14.2;
use XML::LibXML;

my $filename = "xml_doc.xml";
my $parser = XML::LibXML->new();
$parser->keep_blanks(0);
my $dom = $parser->parse_file($filename);

for my $node ($dom->findnodes("/poem/stanza/v"))
{
    my $elm = $dom->createElement('newnode');
    $elm->appendText('This is a new node');
    $_->addChild($elm);
}

say $dom->toString(1);

File 'xml_doc.xml':

<?xml version="1.0" encoding="UTF-8"?>
<poem>
<stanza>
<v>As I was going to Bonner,</v>
<v>Upon my word of honor,</v>
<v>I met a pig</v>
<v>Without a wig,</v>
<v>As I was going to Bonner.</v>
</stanza>
</poem>

The program fails with the error 'Can't call method "addChild" on an undefined value at batch_add_nodes.pl line 16.'

Any tips would be welcome.

Upvotes: 2

Views: 646

Answers (1)

Dave Cross
Dave Cross

Reputation: 69314

You need to make up your mind whether your for loop iterator variable is $node or $_ :-)

If I replace $_->addChild($elm) with $node->addChild($elm) your code works and gives this output:

<?xml version="1.0" encoding="UTF-8"?>
<poem>
  <stanza>
    <v>As I was going to Bonner,<newnode>This is a new node</newnode></v>
    <v>Upon my word of honor,<newnode>This is a new node</newnode></v>
    <v>I met a pig<newnode>This is a new node</newnode></v>
    <v>Without a wig,<newnode>This is a new node</newnode></v>
    <v>As I was going to Bonner.<newnode>This is a new node</newnode></v>
  </stanza>
</poem>

Upvotes: 5

Related Questions