首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用perl XML::LibXML解析

使用perl XML::LibXML解析
EN

Stack Overflow用户
提问于 2011-08-12 14:39:08
回答 1查看 4.4K关注 0票数 4

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

代码语言:javascript
复制
<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代码,例如:

代码语言:javascript
复制
#!/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');

如果我不使用regex替换,脚本就不会被加载来解析。我可以理解新行的剥离,但是为什么我必须从XML响应中删除属性,所以只有当这些行:

代码语言:javascript
复制
<chassis-inventory xmlns="http://xml.juniper.net/junos/10.3D0/junos-chassis">

<chassis junosstyle="inventory">

变成这样:

代码语言:javascript
复制
<chassis-inventory>
<chassis>
  1. 这是XML响应的问题还是XML::LibXML模块的问题?
  2. 有没有一种方法可以让它忽略文件中没有使用regex替换的空行这个事实?

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-12 15:12:21

XPATH表达式失败的原因是名称空间;您需要在上下文中搜索该名称空间。以下是XML::libXML文档的解释

关于名称空间和XPATH的说明: 关于XPath的一个常见错误是假设节点测试由默认命名空间中没有前缀匹配元素的元素名称组成。这种假设是错误的--根据XPath规范,这种节点测试只能匹配没有(即null)命名空间中的元素。 因此,例如,不能将XHTML文档的根元素与$node->find( '/html‘)相匹配,因为’/html‘只有当根元素没有命名空间时才匹配,但是所有XHTML元素都属于名称空间http://www.w3.org/1999/xhtml。(请注意xmlns=“.”命名空间声明也可以在DTD中指定,这使得情况更加糟糕,因为XML文档看起来似乎没有默认的命名空间)。

要处理这个问题,请注册名称空间,然后使用名称空间搜索文档。下面是一个适用于您的示例:

代码语言:javascript
复制
#!/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";
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7041719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档