我试图获取某些XML数据中任何name
元素的section
属性的值。
my $some_att = $fileLocation->findnodes("//section[/@name]");
有人可以解释这种语法有什么问题吗?
请注意,此处的变量$fileLocation
会打开我正在使用的XML的文件位置。
答案 0 :(得分:2)
我假设您正在使用
XML::LibXML
?
解释您正在使用的工具(库,语言,操作系统)以及您所看到的错误行为非常重要。
您的"请注意,此处的变量$fileLocation
会打开我正在使用的XML的文件位置" 令人不安。它没有多大意义(它是一个变量,不能打开任何东西),你选择的标识符暗示它是XML文件的路径。
但是为了能够在其上调用findnodes
,它必须是一个DOM对象,更具体地说是XML::LibXML::Node
的实例或子类。
您的代码看起来应该更像
use XML::LibXML;
my $xml_file = '/path/to/file.xml';
my $dom = XML::LibXML->load_xml(
location => $xml_file
);
my @sections = $dom->findnodes('//section');
for my $section ( @sections ) {
next unless $section->hasAttribute('name');
say $section->getAttribute('name');
}
标量上下文中findnodes
方法的结果不是单一的
XML::LibXML::Node
对象,而是一个
XML::LibXML::NodeList
,
这是重载的,所以它类似于对数组的引用
你不会说出你得到的错误,但是你的"有人可以解释这种语法有什么问题吗?" 我想这个模块拒绝你的XPath表达式?
在本声明中
my $some_att = $fileLocation->findnodes("//section[/@name]")
问题在于谓词 [/@name]
,如果它是正确的,会过滤section
元素,只包含那些name
属性的元素。因为它是一个谓词,所以它不需要子轴,所以应该写成//section[@name]
但是,这只会找到具有section
属性的所有name
元素。要选择属性本身,您需要编写//section/@name
,类似这样的
my $section_names = $fileLocation->findnodes('//section/@name')
然后你会有一个XML::LibXML::NodeList
XML::LibXML::Attr
对象,您可以使用类似于
my @section_names = map { $_->value } $section_names->get_nodelist
您可能更愿意使用XPath表达式section
从所有//section
元素的列表开始。这会给你一个集合
XML::LibXML::Element
对象,您可以使用name
$elem->getAttribute('name')
元素
请记住,您可以使用数组而不是
如果您愿意,可以通过在XML::LibXML::NodeList
调用中选择列表上下文而不是标量上下文来findnodes
个对象,如
暴徒回答
答案 1 :(得分:1)
我不知道Perl,但我认为findnodes()旨在评估XPath表达式。你的表达
"//section[/@name]"
在语法上是正确的,但在语义上,这是无稽之谈。 (顺便说一句,我想知道人们是怎么想出这样的东西的?我只能想象你正在从你不理解的例子中剪切和粘贴,而不回到规范看看它实际意味着什么。) / p>
这里有两个主要错误。
/@name
无效。表达式开头的“/”选择根(文档)节点,而@name选择属性。文档节点没有属性,因此不会选择任何内容。您想要的表达式是//section/@name
。 (一旦你将它们带入Perl-space,你对这些名称所做的就是我所知道的。)