【问题标题】:XML:Find particular node in XML using LibXMLXML:使用 LibXML 在 XML 中查找特定节点
【发布时间】:2018-12-04 10:58:12
【问题描述】:

我有一个 XML 文件,它只有一个名为 import 的节点。我想找到导入的 href 属性。我尝试使用 findnodes(),但它返回一个列表,我必须进一步搜索,所以我希望有一种方法可以找到一个只出现一次的特定节点。 我尝试了 getChildrenByTagName 但这给出了错误

Can't locate object method "getChildrenByTagName" via package "XML::LibXML::Document"

我也尝试了 grep,它给出了类似的错误

Can't locate object method "grep" via package "XML::LibXML::Document"

我的 XML 文件是:

<?xml version="1.0" encoding="UTF-8"?>
<resource name="data" type="application/dictionary+xml">
<schema>
    <import href="tobefound.xml"/>
</schema>
</resource>

到目前为止我的代码是

#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;

my $name = $ARGV[1];
my $dom = XML::LibXML->load_xml(location => $name);
my @node= $dom->findnodes('//import');
print "List: @node\n";

请告诉我是否有一种方法可以只找到一个特定节点而无需遍历整个 dom 并且不必将其存储为列表。谢谢。

【问题讨论】:

  • 如果你知道它只有一个节点,那么就取@node的第一个元素?
  • @tinita 不会不必要地使用列表吗?我能以某种方式找到import 的第一次出现吗?

标签: xml perl xml-parsing libxml2 xml-libxml


【解决方案1】:

XML 不保证唯一性,因此任何类型的搜索都会返回结果列表。该列表的长度可能为 0 或 1,就像 grep 一样。

但简单的答案是抓住第一个结果:

my ($node) = $dom -> findnodes('//import');

失败 - 在您的 xpath 中指定:

my ( $node ) = $dom -> findnodes ( '(//import)[1]' ); 

恐怕我不知道后者是否会在选择“足够”节点时退出。

【讨论】:

  • 好的,所以这基本上是将节点类型转换为标量?抱歉,perl 新手。不过谢谢你,根据需要工作。
  • 它将来自“findnodes”的列表结果分配给左侧的列表。但是 LHS 上的列表只有一个元素,因此任何其他分配都将被丢弃。你可以写:my ( $first_match, @rest_of_matches) = ...,这也许会让发生的事情更清楚——我们只是丢弃了@rest_of_matches
【解决方案2】:

getChildrenByTagName 是 Element 节点的方法,而不是 Document 节点。

my $doc = XML::LibXML->load_xml(location => $name);
my $root_ele = $doc->documentElement();
my ($import_ele) = $root_ele->getChildrenByTagName('import');

您也可以使用 XPath,但等效的 XPath 将是 import(搜索子代),而不是 //import(搜索后代)。

my $doc = XML::LibXML->load_xml(location => $name);
my ($import_ele) = $doc->findnodes('import');

这将返回所有import 节点并保留第一个。但是可以告诉搜索停止查找后找到第一个如下:

my $doc = XML::LibXML->load_xml(location => $name);
my ($import_ele) = $doc->findnodes('import[1]');  # Short for 'import[position()=1]'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2022-01-28
    • 2020-08-05
    • 1970-01-01
    • 2021-06-28
    相关资源
    最近更新 更多