2012-07-27 53 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.