Use XML :: LibXML to replace XML node

Can anyone help me? I need to replace XML node with Perl using a moduleXML::LibXML

This is a snippet of the XML file:

<utenti>
    <utente>
        <username>amministratore</username>
        <useremail>admin@email.com</useremail>
        <password>0000</password>
    </utente>
</utenti>

      

And I need to replace the password value.

Specifically, I have to search in the XML for the user with a specific username (given by the cookie $userCookie

) and replace his password with a variable $newPSW

.

I've tried this:

    my $psw = $doc->findnodes("/utenti/utente[username=\"$userCookie\"]/password");
    my $parent = $psw->parentNode;
    $parent->removeChild($psw);


    my $password = XML::LibXML::Element->new('password');
    $password->appendText( $newPSW );
    $parent->appendChild($password);

      

but every time the browser gives me the following error:

Can't locate object method "parentNode" via package "XML::LibXML::NodeList"

      

I didn't seem to find any method that I am using.

Can anyone help?

+3


source to share


4 answers


The result is XML::LibXML::NodeList

. And this object has no function parentNode

. You have to get the first element of the array and then call the method parentNode

on it.

The first object will be a class object XML::LibXML::Node

and this has funtion parentNode

.



See XML documentation :: LibXML :: Node for details

my $psw = $doc->findnodes("/utenti/utente[username=\"$userCookie\"]/password");
my $parent = $psw->[0]->parentNode;
$parent->removeChild($psw->[0]);

      

+3


source


The problem is that $psw

is is an object XML::LibXML::NodeList

, not just one node - although it should be a list of one node

The simplest solution here is to use a list assignment to grab only the first - and hopefully only - item in the list

It is also possible to change the line separator if you have embedded double quotes



Like this

my ($psw) = $doc->findnodes(qq</utenti/utente[username="$userCookie"]/password>);

      

+3


source


XML :: XSH2 , a wrapper around XML :: LibXML , can make your life easier:

set /utenti/utente[username="amministratore"]/password $newPSW ;

      

+3


source


update: you don't need to communicate with the parent to change the contents of a node

#!/usr/bin/perl --
use strict;
use warnings;
use XML::LibXML 1.70; ## for load_html/load_xml/location
my $xml = q{<a><b><c>old password</c></b></a>};
my $dom = XML::LibXML->new(qw/ recover 2 /)->load_xml(
#~     location => $filepath_or_http,
    string => $xml,
);
my $password = $dom->findnodes('//c')->get_node(0);
$password->removeChildNodes;
$password->appendText('new password');
print "$dom";
__END__
<?xml version="1.0"?>
<a><b><c>new password</c></b></a>

      

You can even ask the parent via xpath :) and using the context context findnodes returns a list of nodes instead of ... NodeList object

#!/usr/bin/perl --
use strict;
use warnings;
use XML::LibXML 1.70; ## for load_html/load_xml/location
my $xml = q{<a><b><c></c></b></a>};
my $dom = XML::LibXML->new(qw/ recover 2 /)->load_xml(
#~     location => $filepath_or_http,
    string => $xml,
);
my( $parent ) = $dom->findnodes('//c/..');
print $parent->nodePath;
__END__
/a/b

      

+2


source







All Articles