1

这对我来说可能是个新手,但我是 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>. 就这样。我尝试了很多方法,最近一次是这个。我已经彻头彻尾地阅读了这些文档。这是我目前在我的代码中的内容:

#!/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();
}

任何建议,链接,任何东西都会受到赞赏。谢谢。

4

2 回答 2

2

只需/在 XPath 的开头添加一个(即 into findnodes)。

于 2012-07-27T16:49:42.777 回答
0

您的代码不起作用,因为您<Tims>在创建 XPath 上下文时使用文档元素作为上下文节点$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.
于 2012-07-28T00:43:07.287 回答