为什么我要将XPathContext与Perl的XML :: LibXML一起使用?

sid*_*com 2 xml perl

此脚本可以使用和不使用XPathContext.我为什么要用它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 "";
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*son 11

使用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 
Run Code Online (Sandbox Code Playgroud)

您需要定义XPathContext以便定义名称空间,以便您可以使名称空间感知XPath查询:

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"]' );
Run Code Online (Sandbox Code Playgroud)

否则,您没有简单的方法来使用名称空间感知的XPath语句.

  • 命名空间没有父子关系.他们彼此独立.我想证明你可以拥有多个命名空间.在XPath中,如果您创建一个没有命名空间的语句,那么您断言您希望元素没有命名空间.在我使用的示例文档中,所有元素都在命名空间中,未加前缀的元素位于默认命名空间中.但是,您需要在XPath语句中使用前缀. (3认同)