findnodes() 中的 xpath 表达式返回空节点列表 [英] xpath expression in findnodes() returning empty nodelist

查看:83
本文介绍了findnodes() 中的 xpath 表达式返回空节点列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XML:

<zoo xmlns="http://www.zoo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.zoo.com employee.xsd">

<area id="1" posizione="nord" nome="scimmie">
    <animale>
        <nome>Gigi</nome>
        <sesso>Male</sesso>
        <eta>3</eta>
    </animale>

    <animale>
        <nome>Gigia</nome>
        <sesso>Female</sesso>
        <eta>2</eta>
    </animale>
</area>

<area id="2" posizione="nord" nome="giraffe">
    <animale>
        <nome>Giro</nome>
        <sesso>Male</sesso>
        <eta>6</eta>
    </animale>

    <animale>
        <nome>Gira</nome>
        <sesso>Female</sesso>
        <eta>5</eta>
    </animale>
</area>
</zoo>

代码:

my $parser = XML::LibXML->new;
my $doc = $parser->parse_file("../xml/animals.xml");
my $root = $doc->getDocumentElement();

my $new_animal = $doc->createElement("animale");

my $name_element = $doc->createElement("nome");
$name_element->appendTextNode($name);

my $gender_element = $doc->createElement("sesso");
$gender_element->appendTextNode($gender);

my $age_element = $doc->createElement("eta");
$age_element->appendTextNode($age);

$new_animal->appendChild($name_element);
$new_animal->appendChild($gender_element);
$new_animal->appendChild($age_element);

my $area_element = $root -> findnodes("//area[\@id=$area]")->get_node(1);

$area_element->appendChild($new_animal);

$area 是一个区域的 id(现在我正在测试通常是 1)

$area is the id of an area (usually 1 now that I'm testing)

我的目的是创建一个新动物并将其添加到适当的区域

my purpose is to create a new animal and to add it to the proper area

但是我遇到了结构问题

    my $area_element = $root -> findnodes("//area[\@id=$area]")->get_node(1);

不起作用,因为 $area_element 是 undef,因为 findnodes 总是返回一个空的节点列表(检查打印 size()).

won't work, because $area_element is undef, because findnodes always returns an empty nodelist (checked printing the size()).

我认为问题在于 findnodes 中的 xpath 表达式,但我不明白出了什么问题,我在另一个库 (XML::XPath) 中使用了相同的表达式并且它正在工作.

I think that the problem is the xpath expression inside findnodes, but I can't understand what's wrong, I use the same expression with another library (XML::XPath) and it's working.

怎么了?

推荐答案

XML 中默认命名空间的 URI 是 http://www.zoo.com,因此您必须在用于要选取的节点的 XPath 表达式.

The URI for the deafult namespace in your XML is http://www.zoo.com, so you must specify this in your XPath expressions for the nodes to be picked up.

这样做的方法是声明一个 XML::LibXML::XPathContext 对象,为这个命名空间分配一个名称.然后可以在 XPath 表达式中使用该名称来访问节点.

The way to do this is to declare a XML::LibXML::XPathContext object that assigns a name to this namespace. The name can then be used in XPath expressions to access the nodes.

如果你写

my $xpc = XML::LibXML::XPathContext->new;
$xpc->registerNs('zoo', 'http://www.zoo.com');

您现在有一个上下文,其中 XML 的默认名称空间被命名为 zoo.现在你可以写

you now have a context in which the XML's default namespace is named zoo. Now you can write

my $area_element = $xpc->findnodes("//zoo:area[\@id=$area]", $doc)->get_node(1);

然后您会找到正确的 元素.

and you will find the correct <area> element.

这篇关于findnodes() 中的 xpath 表达式返回空节点列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆