簡體   English   中英

如何使用XML :: XPath獲取父節點?

[英]How to use XML::XPath to get parent node?

我想使用xPaths解析XML文件。 獲取節點后,我可能需要在其父節點上執行xPath搜索。 我目前使用XML :: XPath的代碼是:

my $xp = XML::XPath->new(filename => $XMLPath);
# get all foo or foos node with a name
my $Foo = $xp->find('//foo[name] | //foos[name]');
if (!$Foo->isa('XML::XPath::NodeSet') || $Foo->size() == 0) {
    # no foo found
    return undef;
} else {
    # go over each and get its bar node
    foreach my $context ($Foo->get_nodelist) {
        my $FooName = $context->find('name')->string_value;
        $xp = XML::XPath->new( context => $context );
        my $Bar = $xp->getNodeText('bar');
        if ($Bar) {
            print "Got $FooName with $Bar\n";
        } else {
            # move up the tree to get data from parent
            my $parent = $context->getParentNode;
            print $parent->getNodeType,"\n\n";
        }
    }
}

我的目標是獲取foo元素名稱及其bar子節點值的哈希,如果foo沒有bar節點,它應該從其父foo或foos節點獲取該節點。

對於這個XML:

<root>
    <foos>
        <bar>GlobalBar</bar>
        <foo>
            <name>number1</name>
            <bar>bar1</bar>
        </foo>
        <foo>
            <name>number2</name>
        </foo>
    </foos>
</root>

我希望:

number1->bar1 
number2->GlobalBar

使用上面的代碼時,我在嘗試獲取父節點時收到錯誤:

無法在未定義的值上調用方法“getNodeType”

任何幫助都感激不盡!

當您嘗試在undef上調用方法時,您將看到該錯誤。 undef上調用方法的最常見原因是無法檢查構造函數方法是否成功。 更改

$xp = XML::XPath->new( context => $context );

成為

$xp = XML::XPath->new( context => $context )
    or die "could not create object with args ( context => '$context' )";

正如Chas所提到的,你不應該創建第二個XML :: XPath對象(文檔也提到了這一點)。 你可以傳遞上下文作為find *方法的第二個參數,或者只是調用上下文節點上的方法,因為你實際上是為了獲得$ FooName。

您還有一些方法調用不符合您的想法(getNodeType不返回元素名稱,而是返回表示節點類型的數字)。

總的來說,下面的更新代碼似乎可以滿足您的需求:

#!/usr/bin/perl

use strict;
use warnings;

use XML::XPath;

my $xp = XML::XPath->new(filename => "$0.xml");
# get all foo or foos node with a name
my $Foo = $xp->find('//foo[name] | //foos[name]');
if (!$Foo->isa('XML::XPath::NodeSet') || $Foo->size() == 0) {
    # no foo found
    return undef;
} else {
    # go over each and get its bar node
    foreach my $context ($Foo->get_nodelist) {
        my $FooName = $context->find('name')->string_value;
        my $Bar = $xp->findvalue('bar', $context); # or $context->findvalue('bar');
        if ($Bar) {
                print "Got $FooName with $Bar\n";
        } else {
                # move up the tree to get data from parent
                my $parent = $context->getParentNode;
                print $parent->getName,"\n\n";
        }
    }
}

最后,提醒一句: XML :: XPath維護得不好,你最好還是使用XML :: LibXML 代碼非常相似。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM