2015-05-19 3 views
3

Может ли кто-нибудь помочь мне, пожалуйста? Мне нужно заменить узел XML с помощью Perl с XML::LibXML модулемИспользуйте XML :: LibXML для замены узла XML

Это фрагмент файла XML:

<utenti> 
    <utente> 
     <username>amministratore</username> 
     <useremail>[email protected]</useremail> 
     <password>0000</password> 
    </utente> 
</utenti> 

И мне нужно заменить значение пароля.

В частности, я должен найти в файле XML пользователя с конкретным именем пользователя (данное cookie $userCookie) и заменить его пароль переменной $newPSW.

Я попытался это:

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); 

, но каждый раз, когда браузер дает мне следующее сообщение об ошибке:

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

Это, кажется, не найти какой-либо метод я использую.

Может кто-нибудь помочь?

ответ

3

В результате получается XML::LibXML::NodeList. И этот объект не имеет функции parentNode. Вы должны получить первый элемент массива, а затем вызвать метод parentNode.

Первый объект будет объектом класса XML::LibXML::Node, и у него есть funtion parentNode.

для получения более подробной информации смотрите документацию XML::LibXML::Node

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

@ Downvoter: пожалуйста, объясните почему !! – Jens

+0

Спасибо .. действительно помогите мне;) –

2

обновление: вам не нужно возиться с родителем, чтобы изменить содержимое узла

#!/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> 

Можно даже попросить parent через xpath :) и используя контекст контекста findnodes возвращает список узлов вместо ... Объект NodeList

#!/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 
3

Проблема заключается в том, что $psw является XML::LibXML::NodeList объектом, а не только один узел - хотя он должен быть список из одного узла

Самым простым решением здесь является использование задания списка, чтобы захватить только первый - и будем надеяться только - элемент в списке

Это также аккуратнее, чтобы изменить строку разделитель, если вы встроили двойные кавычки

Как это

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

XML::XSH2, обертка вокруг XML::LibXML, может сделать вашу жизнь проще:

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