我的XML看起来像这样:
<Servers type="Container">
<Server type="Category">
<HostName type="Property">dmitri-spB</HostName>
<HostIPAddress type="Property">14.341.516.564</HostIPAddress>
在此数据中的大多数情况下,我不需要这些属性 - 或者至少我只在数据中看到过一个可能需要它的情况。无论如何......如果XML看起来像这样:
<Servers>
<Server>
<HostName>dmitri-spB</HostName>
<HostIPAddress>14.341.516.564</HostIPAddress>
......我会做类似的事情:
my $parser = XML::LibXML -> new();
my $tree = $parser -> parse_file ($source_dir."\\".$xmlfiles);
for my $Servers ($tree->findnodes ('/Servers')) {
foreach my $Server ($Servers->findnodes('./Server')) {
$hostname = $Server->findvalue('HostName');
$hostIP = $Server->findvalue('HostIPAddress');
}
}
我试图通过在代码中使用整个标记来使用相同的方法,并得到“XPath错误:表达式无效”。
所以,实际上有两个问题 - 当我不关心属性时如何导航和提取,以及如何在属性显着时执行此操作?也许这是一个XPath问题,但我根本无法将XPath文档与我正在尝试的内容联系起来。建议?
答案 0 :(得分:2)
您可以完全忽略这些属性。它们不是您想象的“整个标记”的一部分,而是每个元素的附加信息。
因此,请按原样使用您的代码,它应该可以正常工作。
要按属性值选择元素,可以在谓词中使用XPath @
表示法。因此,例如,要查找Server
属性为type
的所有Category
元素,您可以编写Server[type = "Category"]
。
您可以使用my $document = XML::LibXML->load_data(location => 'myfile')
创建解析器对象并一次处理源数据。 location
允许您传递文件名或URL,您还可以指定string
并传递包含XML的简单Perl字符串,或IO
并传递打开的文件句柄以供阅读
也无需在单独的循环中迭代路径的每个步骤。例如,您可以像Server
一样处理type
属性为Category
的所有use strict;
use warnings;
use XML::LibXML;
my $doc = XML::LibXML->load_xml(location => "$source_dir/$xmlfiles");
for my $server ($doc->findnodes('/Servers/Server[@type = "Category"]')) {
print ref $server, "\n";
}
个节点
{{1}}