使用perl XML::LibXML来解析

2024-04-14

我正在使用 perl 的 XML::LibXML 模块来解析来自设备的 XML 响应。 看来我成功获取数据的唯一方法是修改设备的 XML 响应。 以下是来自设备的 XML 响应:

<chassis-inventory xmlns="http://xml.juniper.net/junos/10.3D0/junos-chassis">

<chassis junosstyle="inventory">

<name>Chassis</name>

<serial-number>JN111863EAFF</serial-number>

<description>VJX1000</description>

<chassis-module>

<name>Midplane</name>

</chassis-module>

<chassis-module>

<name>System IO</name>

</chassis-module>

<chassis-module>

<name>Routing Engine</name>

<description>VJX1000</description>

<chassis-re-disk-module>

<name>ad0</name>

<disk-size>1953</disk-size>

<model>QEMU HARDDISK</model>

<serial-number>QM00001</serial-number>

<description>Hard Disk</description>

</chassis-re-disk-module>

</chassis-module>

<chassis-module>

<name>FPC 0</name>

<chassis-sub-module>

<name>PIC 0</name>

</chassis-sub-module>

</chassis-module>

<chassis-module>

<name>Power Supply 0</name>

</chassis-module>

</chassis>

</chassis-inventory>

以下是我用来解析和查找序列号的 Perl 代码:

#!/bin/env perl
use strict;
use warnings;
use XML::LibXML;
my $f = ("/var/working/xmlstuff");
sub yeah {
my $ff;
my $f = shift;
open(my $fff,$f);
while(<$fff>) {
$_ =~ s/^\s+$//; 
$_ =~ s/^(<\S+)\s.*?=.*?((?:\/)?>)/$1$2/g;
$ff .= $_;
}
close($fff);
return $ff
}
my $tparse = XML::LibXML->new();
my $ss = $tparse->load_xml( string => &yeah($f));
print map $_->to_literal,$ss->findnodes('/chassis-inventory/chassis/serial-number');

如果我不使用正则表达式替换,则不会加载任何内容供脚本解析。 我可以理解剥离换行符,但为什么我必须从 XML 响应中删除属性,所以只有这些行才有效:

<chassis-inventory xmlns="http://xml.juniper.net/junos/10.3D0/junos-chassis">

<chassis junosstyle="inventory">

变成这样:

<chassis-inventory>
<chassis>
  1. 这是 XML 响应的问题还是 XML::LibXML 模块的问题?

  2. 有没有办法让它忽略文件中存在空行而不使用正则表达式替换的事实?

谢谢您的帮助。


XPATH 表达式失败的原因是命名空间;您需要在上下文中进行搜索。这是来自XML::libXML 文档 http://search.cpan.org/~shlomif/XML-LibXML-1.84/lib/XML/LibXML/Node.pod:

关于命名空间和 Xpath 的注释:

关于 XPath 的一个常见错误是假设节点测试包含 没有前缀的元素名称默认匹配元素 命名空间。这个假设是错误的 - 根据 XPath 规范,例如 节点测试只能匹配 no(即 null)中的元素 命名空间。

因此,例如,无法匹配 XHTML 的根元素 带有 $node->find('/html') 的文档,因为 '/html' 仅在以下情况下匹配 根元素没有命名空间,但所有 XHTML 元素 属于命名空间http://www.w3.org/1999/xhtml http://www.w3.org/1999/xhtml。 (注意 xmlns="..." 命名空间声明也可以在 DTD 中指定, 这使得情况变得更糟,因为 XML 文档看起来像 如果没有默认命名空间)。

要解决此问题,请注册名称空间,然后使用名称空间搜索文档。这是一个应该适合您的示例:

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

my $xml = XML::LibXML->load_xml( location => '/var/working/xmlstuff');
my $xpc = XML::LibXML::XPathContext->new($xml);
$xpc->registerNs('x', 'http://xml.juniper.net/junos/10.3D0/junos-chassis');

foreach my $node ($xpc->findnodes('/x:chassis-inventory/x:chassis/x:serial-number')) {

    print $node->textContent() . "\n";
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用perl XML::LibXML来解析 的相关文章

随机推荐