2010-04-20 31 views
1

該腳本適用於和不適用XPathContext。我爲什麼要用XPathContext爲什麼我應該在Perl的XML :: LibXML中使用XPathContext?

#!/usr/bin/env perl 
use warnings; use strict; 
use XML::LibXML; 
use 5.012; 

my $parser = XML::LibXML->new; 

my $doc = $parser->parse_string(<<EOT); 
<?xml version="1.0"?> 
<xml> 
    Text im Dokument 
    <element id="myID" name="myname" style="old" /> 
    <object objid="001" objname="Object1" /> 
    <element id="002" name="myname" /> 
</xml> 
EOT 
#/ 

# without XPathContext 
my $nodes = $doc->findnodes('/xml/element[@id=002]'); 

# with XPathContext 
#my $root = $doc->documentElement; 
#my $xc = XML::LibXML::XPathContext->new($root); 
#my $nodes = $xc->findnodes('/xml/element[@id=002]'); 


for my $node ($nodes->get_nodelist) { 
    say "Node: ", $node->nodeName; 
    print "Attribute: "; 
    print $_->getName, '=', $_->getValue, ' ' for $node->attributes; 
    say ""; 
} 

回答

9

使用XPathContext元素的主要原因是名稱空間。您的文檔沒有名稱空間,因此XPathContexts不會向您的查詢添加任何內容。現在,假設你實際上有以下XML

my $doc = $parser->parse_string(<<EOT); 
<?xml version="1.0"?> 
<xml xmlns="http://my.company.com/ns/nsone" 
    xmlns:ns2="http://your.company.com/nstwo"> 
    Text im Dokument 
    <ns2:element id="myID" name="myname" style="old" /> 
    <object objid="001" objname="Object1" /> 
    <element id="002" name="myname" /> 
</xml> 
EOT 

您需要以具有定義的命名空間,讓你可以做名稱空間感知的XPath查詢定義一個XPathContext:

my $root = $doc->documentElement; 
my $xc = XML::LibXML::XPathContext->new($root); 
$xc->registerNs("ns2", "http://your.company.com/nstwo"); 
$xc->registerNs("ns1", "http://my.company.com/nsone"); 
my $nodes = $xc->findnodes('/ns1:xml/ns2:element[@id="myID"]'); 

否則,沒有簡單的方法來使用名稱空間感知XPath語句。

+0

'/ ns1:xml/ns2:element [@ id = 002]':是ns2是ns1的子集嗎? – 2010-04-20 09:40:58

+3

名稱空間沒有父子關係。他們彼此獨立。我想證明你可以有多個命名空間。在XPath中,如果你創建了一個沒有命名空間的語句,你斷言你想要的是沒有命名空間的元素。在我使用的示例文檔中,所有元素都位於名稱空間中,前綴不固定的元素位於默認名稱空間中。但是,您需要在XPath語句中使用前綴。 – 2010-04-20 10:51:23

+0

Nic,你上面的例子不會找到任何節點。沒有任何具有「002」標識屬性值的ns2:元素標籤。 xpath表達式「/ ns1:xml/ns2:element [@ id ='myID']」將返回「ns2:element」節點。 xpath表達式「/ ns1:xml/element [@ id = 002]」將返回sid_com原始示例中返回的「element」節點。 – benrifkah 2010-11-03 21:12:13

相關問題