我正在解析一个简单的XML文件,以便从中创建一个平面文本文件。期望的结果显示在示例XML下面。 XML有一种头 - 详细结构(分别是Assembly_Info和Part),有一个唯一的头节点,后跟任意数量的详细记录节点,所有节点都是兄弟节点。在深入了解标题下的元素之后,我无法找到返回“up”的方法,然后选择所有兄弟节点。
XML文件如下所示:
<?xml version="1.0" standalone="yes" ?>
<Wrapper>
<Record>
<Product>
<prodid>4094</prodid>
</Product>
<Assembly>
<Assembly_Info>
<id>DF-7A</id>
<interface>C</interface>
</Assembly_Info>
<Part>
<status>N/A</status>
<dev_name>0000</dev_name>
</Part>
<Part>
<status>Ready</status>
<dev_name>0455</dev_name>
</Part>
<Part>
<status>Ready</status>
<dev_name>045A</dev_name>
</Part>
</Assembly>
<Assembly>
<Assembly_Info>
<id>DF-7A</id>
<interface>C</interface>
</Assembly_Info>
<Part>
<status>N/A</status>
<dev_name>0002</dev_name>
</Part>
<Part>
<status>Ready</status>
<dev_name>0457</dev_name>
</Part>
</Assembly>
</Record>
</Wrapper>
对于每个程序集,我需要读取Assembly_Info中我成功完成的两个元素的值。但是,我想阅读与Assembly相关的每个Part记录。目标是将文件“扁平”为:
prodid id interface status dev_name
4094 DF-7A C N/A 0000
4094 DF-7A C Ready 0455
4094 DF-7A C Ready 045A
4094 DF-7A C N/A 0002
4094 DF-7A C Ready 0457
我正在尝试使用findnodes()来执行此操作,因为这是我认为我理解的唯一工具。不幸的是,我的代码读取了整个文件foreach中的所有Part记录 - 因为我能够找到Part节点的唯一方法是从根开始。如果你愿意,我不知道如何改变'我在哪里';告诉findnodes从当前父节点开始。代码如下所示:
my $parser = XML::LibXML -> new();
my $tree = $parser -> parse_file ('DEMO.XML');
for my $product ($tree->findnodes ('/Wrapper/Record/Product/prodid')) {
$prodid = $product->textContent();
}
foreach my $assembly ($tree->findnodes ('/Wrapper/Record/Assembly')){
$assemblies++;
$parts = 0;
for my $assembly ($tree->findnodes ('/Wrapper/Record/Assembly/Assembly_Info')) {
$id = $assembly->findvalue('id');
$interface = $assembly->findvalue('interface');
}
foreach my $part ($tree->findnodes ('/Wrapper/Record/Assembly/Part')) {
$parts++;
$status = $part->findvalue('status');
$dev_name = $part->findvalue('dev_name');
}
print "Assembly No: ", $assemblies, " Parts: ",$parts, "\n";
}
在我进入Assembly_Info深度之后,如何获得给定Assembly的Part节点?有一点我没有得到,我认为问题可能是我认为这是“导航”或移动光标,如果你愿意的话。 XPath路径表达式的例子对我没有帮助。
答案 0 :(得分:1)
您可以使用任何其他节点,尤其是子节点,而不是始终使用$tree
作为findnodes
方法的起点。然后你可以使用相对的XPath表达式。例如:
for my $record ($tree->findnodes('/Wrapper/Record')) {
for my $assembly ($record->findnodes('./Assembly')) {
for my $part ($assembly->findnodes('./Part')) {
}
}
}