用perl XML::Simple解析XML文件

在Perl中解析XML的方法最常见的就是使用 XML::DOM 和 XML::Simple了。 XML::DOM过于庞大,而且解析结果是一个DOM树,操作也不方便。对于小型且不复杂的XML文件,XML::DOM真是杀鸡用牛刀。这时就轮到轻便的XML::Simple上场了。

XML::Simple如其名,真的很简单。假设XML内容如下:

<opt>
    <user login="grep" fullname="Gary R Epstein" />
    <user login="stty" fullname="Simon T Tyson" >
        <session pid="12345"/>
    </user>
    <text>This is a test.</text>
</opt>

那么只需这样写:

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

$xml = XMLin('sample.xml');
print Dumper($xml);

就可以轻而易举地将XML解析成一个hash,然后用foreach依次处理即可。

 

$VAR1 = {
          'text' => 'This is a test.',
          'user' => [
                    {
                      'fullname' => 'Gary R Epstein',
                      'login' => 'grep'
                    },
                    {
                      'session' => {
                                   'pid' => '12345'
                                 },
                      'fullname' => 'Simon T Tyson',
                      'login' => 'stty'
                    }
                  ]
        };

可以发现如下规律:

  • 元素的标签名被用于hash的key。
  • 单个元素的内容作为hash的value,多个重复的元素的内容被放到一个数组引用中作为hash的value
  • 属性和子元素都以hash的key=>value对出现在元素的内容中

一个问题是,对单个元素和多个重复元素的处理结果不一致,就会导致foreach处理时比较麻烦(需要区分是标量还是数组引用),如上面的 text 和 user 的值。解决方法是添加选项 ForceArray => 1,就可以强制单个元素也放到数组引用中。

$xml = XMLin('sample.xml', ForceArray => 1);
print Dumper($xml);

运行结果(部分):

$VAR1 = {
          'text' => [
                    'This is a test.'
                  ],
          'user' => [
......

另一个问题是,如果你的元素属性中包含id、name或key,那么元素就不再放到数组引用中,而是放到 hash引用中。比如下面的XML,注意与上面的结果的区别:

<opt>
    <user id="grep" fullname="Gary R Epstein" />
    <user id="stty" fullname="Simon T Tyson">
        <session pid="12345"/>
    </user>
    <text>This is a test.</text>
</opt>
$VAR1 = {
          'text' => [
                    'This is a test.'
                  ],
          'user' => {
                    'grep' => {
                              'fullname' => 'Gary R Epstein'
                            },
                    'stty' => {
                              'session' => [
                                           {
                                             'pid' => '12345'
                                           }
                                         ],
                              'fullname' => 'Simon T Tyson'
                            }
                  }
        };

user的内容不再是数组引用,而是hash引用,而id='grep'也变成了key存在。

要想禁用这个功能,应当指定选项 KeyAttr => ''。这个选项就是说,解析时应该把哪些属性作为hash的key来使用,默认值是['id', 'name', 'key']。

在XML::Simple的文档中,所有的选项都有详细说明,而KeyAttr和ForceArray选项被标为important,可见它们是多么常用了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值