XML:使用LibXML查找XML中的特定节点

时间:2018-12-04 10:58:12

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

我有一个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,也不必将其存储为列表。谢谢。

2 个答案:

答案 0 :(得分:1)

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

但简单的答案是仅获得第一个结果:

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

失败-在您的xpath中指定:

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

恐怕我不知道当选择了“足够”的节点时,后者实际上是否可以纾困。

答案 1 :(得分:1)

getChildrenByTagName是元素节点而不是文档节点的一种方法。

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]'