使用Perl解析XML iLO响应文件

时间:2009-08-03 06:33:58

标签: xml perl parsing

我有我的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> 

1 个答案:

答案 0 :(得分:2)

这取决于,和往常一样,有很多方法可以做到这一点。主要取决于(实际)文件的大小。如果它很大,我建议使用像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