使用XML :: LibXML替换XML节点

时间:2015-05-19 09:07:53

标签: xml perl

是的,有人能帮帮我吗?我需要使用Perl替换带有XML::LibXML模块

的XML节点

这是XML文件的片段:

<utenti>
    <utente>
        <username>amministratore</username>
        <useremail>admin@email.com</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"

似乎找不到我使用的任何方法。

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:3)

结果是XML::LibXML::NodeList。此对象没有函数parentNode。您必须获取数组的第一个元素,然后在其上调用方法parentNode

第一个对象是类XML::LibXML::Node的对象,它有一个功能parentNode

有关详细信息,请参阅XML::LibXML::Node

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

答案 1 :(得分:3)

问题是$psw是一个XML::LibXML::NodeList对象,而不仅仅是一个节点 - 尽管它应该是一个节点的列表

这里最简单的解决方案是使用列表赋值来抓取列表中的第一个 - 并且希望只有 - 元素

如果嵌入双引号

,也可以更改字符串分隔符

喜欢这个

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

答案 2 :(得分:3)

XML::XSH2XML::LibXML的包装,可以让您的生活更轻松:

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

答案 3 :(得分: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>

您甚至可以通过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