使用LibXML提取一个节点

时间:2012-07-27 16:46:08

标签: perl xpath xml-parsing libxml2

这对我来说可能是非常新手,但我是Perl LibXML(和XPath)的新手。我有这个XML文档:

<Tims
    xsi:schemaLocation="http://my.location.com/namespace http://my.location.com/xsd/Tims.xsd"
    xmlns="http://my.location.com/namespace"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
        <Error>Too many entities for operation.  Acceptable limit is 5,000 and 8,609 were passed in.</Error>
        <Timestamp>2012-07-27T12:06:24-04:00</Timestamp>
        <ExecutionTime>41.718</ExecutionTime>
</Tims>

我想做的就是获得<Error>的价值。就这样。我已经尝试了很多方法,最近一次是this。我一直在阅读文档。这就是我目前在我的代码中所拥有的:

#!/usr/bin/perl -w

my $xmlString = <<XML;
<?xml version="1.0" encoding="ISO-8859-1"?>
<Tims
    xsi:schemaLocation="http://my.location.com/namespace http://my.location.com/xsd/Tims.xsd"
    xmlns="http://my.location.com/namespace"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
    <Error>Too many entities for operation.  Acceptable limit is 5,000 and 8,609 were passed in.</Error>
    <Timestamp>2012-07-27T12:06:24-04:00</Timestamp>
    <ExecutionTime>41.718</ExecutionTime>
</Tims>
XML

use XML::LibXML;

my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($xmlString);
my $root = $doc->documentElement();
my $xpc = XML::LibXML::XPathContext->new($root);

$xpc->registerNs("x", "http://my.location.com/namespace");

foreach my $node ($xpc->findnodes('x:Tims/x:Error')) {
        print $node->toString();
}

任何建议,链接,任何事情都表示赞赏。感谢。

2 个答案:

答案 0 :(得分:2)

只需在XPath的开头添加/(即进入findnodes)。

答案 1 :(得分:0)

您的代码无效,因为在创建XPath上下文<Tims>时使用文档元素$xpc作为上下文节点。 <Error>元素是其中的直接子元素,因此您只需要编写

$xpc->findnodes('x:Error')

或另一种方法是使用绝对XPath,它指定文档根目录

的路径
$xpc->findnodes('/x:Tims/x:Error')

这样,$xpc的上下文节点是什么并不重要。

但正确的方法是忘记完全获取元素节点并使用文档根作为上下文节点。您还可以使用findvalue代替findnodes来获取错误消息的文本而不使用封闭标记:

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

my $xpc = XML::LibXML::XPathContext->new($doc);
$xpc->registerNs('x', 'http://my.location.com/namespace');

my $error= $xpc->findvalue('x:Tims/x:Error');
print $error, "\n";

<强>输出

Too many entities for operation.  Acceptable limit is 5,000 and 8,609 were passed in.