【问题标题】:Why should I use XPathContext with Perl's XML::LibXML?为什么我应该将 XPathContext 与 Perl 的 XML::LibXML 一起使用?
【发布时间】:2010-04-20 07:36:08
【问题描述】:

此脚本在有和没有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 "";
}

【问题讨论】:

    标签: xml perl


    【解决方案1】:

    使用 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 
    

    您需要定义一个 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"]' );
    

    否则,您将无法使用可识别命名空间的 XPath 语句的简单方法。

    【讨论】:

    • '/ns1:xml/ns2:element[@id=002]': ns2 是 ns1 的子集吗?
    • 命名空间没有父子关系。它们彼此独立。我想证明您可以拥有多个名称空间。在 XPath 中,如果您创建一个没有命名空间的语句,那么您就是在断言您想要没有命名空间的元素。在我使用的示例文档中,所有元素都在命名空间中,无前缀元素在默认命名空间中。但是,您需要在 XPath 语句中使用前缀。
    • Nic,您上面的示例找不到任何节点。没有任何 ns2:element 标记的 id 属性值为“002”。 xpath 表达式“/ns1:xml/ns2:element[@id='myID']”将返回“ns2:element”节点。而 xpath 表达式“/ns1:xml/element[@id=002]”将返回 sid_com 原始示例中返回的“元素”节点。
    • @benrifkah,令人印象深刻,我已经六个月没注意到那个错字了!谢谢!
    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 2019-04-12
    • 2022-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多