gpt4 book ai didi

xml - 如何在 perl 中找出元素的 xpath?

转载 作者:行者123 更新时间:2023-12-03 17:32:01 25 4
gpt4 key购买 nike

我试图弄清楚是否有确定 XML 节点的 xpath 的好方法。

目前,我正在这样做:

#!/usr/bin/env perl

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig->parse( \*DATA );
print $twig ->get_xpath( '/root/fish/carrot[@colour="orange"]/pie', 0 )->text,
"\n";

foreach my $node ( $twig->get_xpath('//*') ) {
my @path_tags;
my @path_with_att;
my $cursor = $node;
while ($cursor) {
unshift( @path_tags, $cursor->tag );

my $att_path = "";
if ( $cursor->atts ) {
$att_path = join( "",
map { "[@" . $_ . "=\"" . $cursor->att($_) . "\"]" }
keys %{ $cursor->atts } );
}
unshift( @path_with_att, $cursor->tag . $att_path );
$cursor = $cursor->parent;
}

print join( "/", @path_tags ), "\n";

my $xpath_with_atts = "/" . join( "/", @path_with_att );
print $xpath_with_atts, "\n";
print "Found:", $twig->get_xpath( $xpath_with_atts, 0 )->tag, "\n";
}

__DATA__
<root>
<fish skin="scaly" home="pond">
<carrot colour="orange">
<pie>This value</pie>
</carrot>
</fish>
</root>

我正在遍历结构(使用通配符 xpath,也许有点讽刺 - 但关键是我希望能够在例如 Twig 处理程序中做到这一点)。

然后递归遍历树以找出 xpath 的两个变体当前节点的(有和没有元素)。这当然是认识到 xpath 不一定是唯一的,因此很可能存在重复(最后一个“找到”纯粹是一个验证步骤)。

但这是因为我在我喜欢的两个 XML 库( XML::TwigXML::LibXML)中的任何一个中都找不到 what-is-my-xpath 方法。

所以我的问题是——在我可以(并且应该)使用的 XML 库中实际上是否有一个内置机制?如果没有,实际上有什么理由不这样做吗?

我的意思是,我上面的示例工作,但我想知道是否存在一些细微差别,这种方法(或类似的方法)对于整个 XML 规范都不可行。

最佳答案

XML::LibXML 有 $node->nodePath() .

use strict;
use warnings;
use feature qw( say );

use XML::LibXML qw( );

my $xml = <<'__EOI__';
<root>
<fish>
<carrot colour="purple"><pie/></carrot>
<carrot colour="orange"><pie/></carrot>
<carrot colour="blue"><pie/></carrot>
</fish>
</root>
__EOI__

my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($xml);
say $_->nodePath()
for $doc->findnodes("//pie");

输出:
/root/fish/carrot[1]/pie
/root/fish/carrot[2]/pie
/root/fish/carrot[3]/pie

它使用位置而不是属性来识别歧义,因为属性可能无法唯一地识别元素。

请注意,由于缺少 [1],如果在另一个文档中使用该路径可能会产生多个结果。在原始文档中只有一个的节点上。

至于为什么 XML::Twig 没有,这不是一个非常有用的功能。如果您只使用一个文档,则您已经拥有对该节点的引用。如果您想设计一条适用于多个文档的路径,那么模块不可能知道正确的路径应该是什么。例如,以下哪项是正确的?
/a/b
/a/b[1]
/a/b[@id="123"]
/a/b[@default="1"]
/a/b[@id="123" && @default="1"]

关于xml - 如何在 perl 中找出元素的 xpath?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33433501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com