【问题标题】:Extracting a multiple level XML using Perl使用 Perl 提取多级 XML
【发布时间】:2011-04-19 06:37:01
【问题描述】:

我正在尝试从 XML 文件中提取数据。

XML格式如下:

<notifications>
<notification name="ccmSmtp" oid="1.3.6.1" status="current">
  <objects>
    <object module="callhome" name="ccmSmtp"/>
  </objects>
  <description>
     This is a description
  </description>
</notification>
<notification name="ccmAlertGroup" oid="1.3.6.1" status="current">
  <objects>
    <object module="callhome" name="callHome"/>
  </objects>
  <description>
       This is a description
  </description>
</notification>
<notification name="ccmAlert" oid="1.3.6.1" status="current">
  <objects>
    <object module="callhome" name="callHome"/>
  </objects>
  <description>
    This is a description
  </description>
</notification>
<notification name="ccmSmtp" oid="1.3.6.1" status="current">
  <objects>
  </objects>
  <description>
      This is a description
  </description>
</notification>
</notifications>

我编写了以下代码来从 example.xml 文件中提取通知节点。

#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

$xml = new XML::Simple;

$data = $xml->XMLin("example.xml",KeyAttr => {
  notifications => notification => 'name'
});

$notification = $data->{notifications};

print Dumper($notification);

当我运行上面的 Perl 文件时,我得到以下输出:

$VAR1 = {
  'notification' => [
      {
        'objects' => {
          'object' => {
            'name' => 'ccmSmtp',
            'module' => 'callhome'
          }
        },
        'status' => 'current',
        'oid' => '1.3.6.',
        'name' => 'ccmSmtp',
        'description' => ' This is a mib '
      },
      {
        'objects' => {
          'object' => {
            'name' => 'callHome',
            'module' => 'module'
          }
        },
        'status' => 'current',
        'oid' => '1.3.6.1.4',
        'name' => 'ccmAlert',
        'description' => 'This is a description'
      },
      {
        'objects' => {
          'object' => {
            'name' => 'callHome',
            'module' => 'homemib'
          }
        },
        'status' => 'current',
        'oid' => '1.3.6.1.4',
        'name' => 'ccmAlertf',
        'description' => 'This is a description'
      },
      {
        'objects' => {},
        'status' => 'current',
        'oid' => '1.3.6.1',
        'name' => 'ccmSmtp',
        'description' => ' This is an example'
      }
    ]
};

我的问题是,如何提取通知节点的内容并将值存储在单独的变量/数组中?

【问题讨论】:

    标签: xml perl parsing xml-parsing


    【解决方案1】:

    一般来说,为了从 XML 中提取项目,我会从 XPath 开始。 Perl 有一个 XPath 包,甚至可能在您已经使用的 XML 包中。

    【讨论】:

      【解决方案2】:

      $notification 只是一个散列的引用,其中一个键“通知”具有散列数组。

      你可以循环遍历它

      for my $n ( @{$notification->{notification}} ) {
          # ie. to get status out, this is same for description,oid,name
          my $status = $n->{status};
      
          # To get the nested 'objects' data object module value (phew)
          my $object_module = $n->{status}{object}{module};
      
      }
      

      【讨论】:

      • 运行代码建议给出以下输出“不是数组引用”
      【解决方案3】:

      我不清楚你想要什么。您发布的代码不会产生该输出,因为它不会编译,但如果您改为编写

      my $data = $xml->XMLin("x.xml", KeyAttr => ['notification']);
      print Dumper $data;
      

      那么你会得到完全正确的。现在 $data->{notification} 是对四个哈希数组(对应四个元素)的引用,可以访问为

      my $note0 = $data->{notification}[0];
      

      等等。这是否回答了您的问题?

      【讨论】:

      • 嗨 Borodin,我按照你说的尝试了,但是通过打印 $note0 并没有给我任何输出。 :-(
      • 您确定在每种情况下都有“通知”而不是“通知”吗?您还应该在您编写的所有内容的顶部“使用严格”和“使用警告”,以获得有关出现的任何错误的更好信息。
      【解决方案4】:

      我会像下面这样循环:

      foreach $NOTIFICATION( @{$data->{'notification}}) 
      {   
      foreach $OBJECT (@{$NOTIFICATION->{'OBJECT'}}) 
      {
      $name=$NOTIFICATION->{'name'};                                 $module=$OBJECT->{'module'}; 
      
      Print $name , $module 
      }
      }
      

      【讨论】:

      • 您至少应该提供一些缩进并稍微解释一下您的解决方案...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 2012-09-30
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      相关资源
      最近更新 更多