【问题标题】:Parse XML iLO response file with Perl使用 Perl 解析 XML iLO 响应文件
【发布时间】:2009-08-03 06:33:57
【问题描述】:

我的 iLO HP 服务器生成了以下 XML 文件, 你有我如何解析它的任何例子吗?请参阅下面的示例 XML 文件。 我想从中提取风扇速度和温度。

<?xml version="1.0"?>
<GET_EMBEDDED_HEALTH_DATA>
<FANS>
   <FAN>
      <LABEL VALUE = "Fan 1"/>
      <ZONE VALUE = "System"/>
      <STATUS VALUE = "Ok"/>
      <SPEED VALUE = "81" UNIT="Percentage"/>
   </FAN>
   <FAN>
      <LABEL VALUE = "Fan 2"/>
      <ZONE VALUE = "System"/>
      <STATUS VALUE = "Not Installed"/>
      <SPEED VALUE = "n/a" UNIT="n/a"/>
   </FAN>
   <FAN>
      <LABEL VALUE = "Fan 3"/>
      <ZONE VALUE = "System"/>
      <STATUS VALUE = "Ok"/>
      <SPEED VALUE = "81" UNIT="Percentage"/>
   </FAN>
   <FAN>
      <LABEL VALUE = "Fan 4"/>
      <ZONE VALUE = "System"/>
      <STATUS VALUE = "Not Installed"/>
      <SPEED VALUE = "n/a" UNIT="n/a"/>
   </FAN>
   <FAN>
      <LABEL VALUE = "Fan 5"/>
      <ZONE VALUE = "CPU 1"/>
      <STATUS VALUE = "Ok"/>
      <SPEED VALUE = "81" UNIT="Percentage"/>
   </FAN>
   <FAN>
      <LABEL VALUE = "Fan 6"/>
      <ZONE VALUE = "CPU 2"/>
      <STATUS VALUE = "Not Installed"/>
      <SPEED VALUE = "n/a" UNIT="n/a"/>
   </FAN>
</FANS>
<TEMPERATURE>
   <TEMP>
      <LABEL VALUE = "Temp 1"/>
      <LOCATION VALUE = "Ambient"/>
      <STATUS VALUE = "Ok"/>
      <CURRENTREADING VALUE = "32" UNIT="Celsius"/>
      <CAUTION VALUE = "40" UNIT="Celsius"/>
      <CRITICAL VALUE = "45" UNIT="Celsius"/>
   </TEMP>
   <TEMP>
      <LABEL VALUE = "Temp 2"/>
      <LOCATION VALUE = "Memory"/>
      <STATUS VALUE = "Ok"/>
      <CURRENTREADING VALUE = "48" UNIT="Celsius"/>
      <CAUTION VALUE = "110" UNIT="Celsius"/>
      <CRITICAL VALUE = "120" UNIT="Celsius"/>
   </TEMP>
   <TEMP>
      <LABEL VALUE = "Temp 3"/>
      <LOCATION VALUE = "CPU 1"/>
      <STATUS VALUE = "Ok"/>
      <CURRENTREADING VALUE = "30" UNIT="Celsius"/>
      <CAUTION VALUE = "100" UNIT="Celsius"/>
      <CRITICAL VALUE = "100" UNIT="Celsius"/>
   </TEMP>
   <TEMP>
      <LABEL VALUE = "Temp 4"/>
      <LOCATION VALUE = "CPU 1"/>
      <STATUS VALUE = "Ok"/>
      <CURRENTREADING VALUE = "30" UNIT="Celsius"/>
      <CAUTION VALUE = "100" UNIT="Celsius"/>
      <CRITICAL VALUE = "100" UNIT="Celsius"/>
   </TEMP>
   <TEMP>
      <LABEL VALUE = "Temp 5"/>
      <LOCATION VALUE = "I/O Board"/>
      <STATUS VALUE = "Ok"/>
      <CURRENTREADING VALUE = "46" UNIT="Celsius"/>
      <CAUTION VALUE = "63" UNIT="Celsius"/>
      <CRITICAL VALUE = "68" UNIT="Celsius"/>
   </TEMP>
   <TEMP>
      <LABEL VALUE = "Temp 6"/>
      <LOCATION VALUE = "CPU 2"/>
      <STATUS VALUE = "n/a"/>
      <CURRENTREADING VALUE = "n/a" UNIT="n/a"/>
      <CAUTION VALUE = "100" UNIT="Celsius"/>
      <CRITICAL VALUE = "100" UNIT="Celsius"/>
   </TEMP>
   <TEMP>
      <LABEL VALUE = "Temp 7"/>
      <LOCATION VALUE = "CPU 2"/>
      <STATUS VALUE = "n/a"/>
      <CURRENTREADING VALUE = "n/a" UNIT="n/a"/>
      <CAUTION VALUE = "100" UNIT="Celsius"/>
      <CRITICAL VALUE = "100" UNIT="Celsius"/>
   </TEMP>
</TEMPERATURE> 

【问题讨论】:

  • 这不是有效的 XML,这是它真正返回的吗?如果是这样,请不要使用严格的解析器,因为这将是一个问题。来自 xmllint:解析器错误:标记 GET_EMBEDDED_HEALTH_DATA 第 2 行中的数据过早结束
  • -1 根据您下面的 cmets,很明显您有安装问题,而不是解析问题。删除这个问题并开始另一个问题。

标签: xml perl parsing


【解决方案1】:

这取决于,并且像往常一样有很多方法可以做到这一点。主要取决于(实际)文件的大小。如果它很大,我建议在解析之前使用XML::Twig 之类的模块将其切成小块。它很小,就像您的示例文件一样,几乎可以做任何事情。例如XML::LibXML::XPathContext 可以这样做(注意:您会明智地在解析中添加一些错误检查代码并可能事先验证 xml):

#!/us/bin/perl                                                                                          

use warnings;                                                                                            
use strict;                                                                                              

use XML::LibXML;                                                                                         
use XML::LibXML::XPathContext;                                                                           

my $parser = XML::LibXML->new();                                                                         

my $doc = $parser->parse_file('test.xml');                                                               

my @nodes = $doc->findnodes('//FAN/SPEED');                                                              

foreach my $node(@nodes){                                                                                
  printf("fan: %s %s\n", $node->getAttribute('VALUE'), $node->getAttribute('UNIT'));                     
}   

给出这个输出:

fan: 81 Percentage
fan: n/a n/a
fan: 81 Percentage
fan: n/a n/a
fan: 81 Percentage
fan: n/a n/a 

您可能需要quick intro to XPath

【讨论】:

  • 知道我是否可以使用 Simple XML 吗?
  • 是的...我似乎无法在我的 debian 机器上安装 XPath,即使使用“apt-get install libxml-libxml-perl”
  • @Mike: 除非你是 etch 或更老的,否则应该这样做。你怎么会失败?
  • @ysth:我正在使用 Lenny。我进行了 apt-get 安装,但是当我尝试运行代码时仍然收到以下信息:Can't locate XML/LibxML/XPathContext.pm in @INC(@INC 包含:/etc/perl /usr/local/ lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/ local/lib/site_perl .) 在 perl2.pl 第 6 行。BEGIN 失败——编译在 perl2.pl 第 6 行中止。
  • 您当然可以使用 XML::Simple 来完成这项任务,但我倾向于避开 XML::Simple,因为我有过这样的经历想。但已经有一段时间了,现在可能已经改变了。像往常一样 YMMV。
猜你喜欢
  • 2017-10-28
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 2013-07-17
  • 2017-06-29
  • 2019-12-08
相关资源
最近更新 更多