2012-07-27 139 views
1

这可能是我的新手,但我是Perl LibXML(和XPath)的新手。我有这个XML文档:使用LibXML提取一个节点

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

任何建议,链接,任何感激。谢谢。

+0

你尝试X:蒂姆斯/ X:错误/文本( )在你的xpath表达式中? – 2012-07-27 16:48:06

+0

我试过了你的建议,但它仍然是空的。 – 2012-07-27 17:11:34

回答

2

只需在XPath开头添加/(即输入findnodes)即可。

+0

那真是令人尴尬。你的生活和学习我猜。谢谢。 – 2012-07-27 17:11:13

+0

或删除'x:Tims /' – ikegami 2012-07-27 17:39:49

0

您的代码不起作用,因为您在创建XPath上下文$xpc时使用文档元素<Tims>作为上下文节点。该<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.