【问题标题】:Xpath is not working with XML::Twig::XPath::EltXpath 不适用于 XML::Twig::XPath::Elt
【发布时间】:2018-04-28 20:09:12
【问题描述】:

我有以下 XML。

<Path>
  <To>
    <My>
      <Node key="11">
        <ChildA>1A</ChildA>
        <ChildB key="Key1">1B</ChildB>
        <ChildC>
            <ChildD>ValD</ChildD>
        </ChildC>
      </Node>
      <Node key="22">
        <ChildA>2A</ChildA>
        <ChildB key="Key2">2B</ChildB>
        <ChildC>
            <ChildD>ValD</ChildD>
        </ChildC>
      </Node>
    </My>
  </To>
</Path>

我正在尝试使用 XML::Twig::XPath 解析这个 xml。 以下是我使用 XPath 语法解析它并从中提取元素的代码。

use 5.010;
use strict;
use warnings FATAL => 'all';
use XML::Twig::XPath;  #Issue with this shit as this thing was up to data but XML::XPath was not installed. So I did cpanm XML::XPath
use XML::Twig;
use Data::Dumper;
my @xml;

$xml[0] = q|<Path>
  <To>
    <My>
      <Node key="11">
        <ChildA>1A</ChildA>
        <ChildB key="Key1">1B</ChildB>
        <ChildC>
            <ChildD>ValD</ChildD>
        </ChildC>
      </Node>
      <Node key="22">
        <ChildA>2A</ChildA>
        <ChildB key="Key2">2B</ChildB>
        <ChildC>
            <ChildD>ValD</ChildD>
        </ChildC>
      </Node>
    </My>
  </To>
</Path>|;

my $twig = XML::Twig::XPath->new(pretty_print => 'indented')->parse($xml[0]);

#Finding the whole Node, using xpath. This shit also works if you have Twig, not XPath.
my @constraint = $twig->findnodes('/Path/To/My/Node[@key="22"]');
say $constraint[0]->sprint;
say ref($constraint[0]);

my $child_key = $constraint[0]->find('//ChildB/@key');
say $child_key;

$constraint[0] 正确地打印 XML 节点。

我希望 $child_key 是 Key2 但结果却是 Key1Key2

我可能做错了什么?如果我进行完整的 XPath 搜索,它会给出正确的输出。

【问题讨论】:

    标签: xml perl xpath xml-twig


    【解决方案1】:

    //ChildB/@key xpath 表达式意味着它从根元素开始,并在任何元素中查找元素 ChildB 和属性 @key

    令人困惑的是,您的树枝$constraint[0]没有完全从树上取下来。这就像完整文档树的某些部分的视图,所以// 实际上是在完整的树中查找。它从文档的根目录开始,而不是从 &lt;Node key="22"&gt; 元素开始。

    您需要告诉您的find 使用. 启动当前元素。

    #                                     V
    my $child_key = $constraint[0]->find('.//ChildB/@key');
    

    现在你的输出只有

    Key2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      • 2017-08-13
      相关资源
      最近更新 更多