shloro
shloro

Reputation: 115

append value to xml node using perl

I'm trying to append a string between <value></value>,

<?xml version="1.0" encoding="UTF-8"?>
<rs:alarm-request throttlesize="100" xmlns:rs="http://url.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.url.com">
    <rs:attribute-filter>
    <search-criteria xmlns="http://www.url">
    <filtered-models>
      <equals>
        <attribute id="0x1144f50">
        <value></value>
        </attribute>
      </equals>
      </filtered-models>
    </search-criteria>
  </rs:attribute-filter>
    <!-- Models of Interest -->
    <rs:target-models>
    </rs:target-models>
</rs:alarm-request>

I used the following code, but I'm keep getting: Can't locate object method "appendTextNode" via package "XML::LibXML::NodeList"

my $parser     = XML::LibXML->new();

# Insert devices MH to GETdevices_xmlbody template
my $doc = $parser->parse_file($current_working_dir.'\GETdevices_xmlbody.xml');
my $elem = $doc->findnodes('//rs:attribute-filter/search-criteria/filtered-models/equals/attribute/value');

# $elem->removeChildNodes();
$elem->appendTextNode('STRING');

Upvotes: 1

Views: 704

Answers (2)

Birei
Birei

Reputation: 36262

You can use XML::Twig too:

Content of script.pl:

#!/usr/bin/env perl

use warnings;
use strict;
use XML::Twig;

my $twig = XML::Twig->new(
    twig_handlers => {
        '//rs:attribute-filter/search-criteria/filtered-models/equals/attribute/value' => sub {
            $_->set_text('STRING');
        },  
    },  
    pretty_print => 'indented',
)->parsefile( shift )->print;

Run it like:

perl script.pl xmlfile

That yields:

<?xml version="1.0" encoding="UTF-8"?>
<rs:alarm-request throttlesize="100" xmlns:rs="http://url.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.url.com">
  <rs:attribute-filter>
    <search-criteria xmlns="http://www.url">
      <filtered-models>
        <equals>
          <attribute id="0x1144f50">
            <value>STRING</value>
          </attribute>
        </equals>
      </filtered-models>
    </search-criteria>
  </rs:attribute-filter>
  <!-- Models of Interest --> 
  <rs:target-models></rs:target-models>
</rs:alarm-request>

Upvotes: 4

ikegami
ikegami

Reputation: 385789

You asked to get all the nodes matching your criteria. You need to loop over them.

my $elems = $doc->findnodes('...');
for my $elem ($elems->get_nodelist) {
   ...
}

Simpler:

my @elems = $doc->findnodes('...');
for my $elem (@elems) {
   ...
}

If you just expect exactly one, you could just grab the first one.

my ($elem) = $doc->findnodes('...');

Upvotes: 3

Related Questions