从小白到大神需要多久????
全部博文(12)
2015年(12)
分类: PERL
2015-03-28 00:44:46
对于小型且不复杂的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' }
]
};
可以发现如下规律:
一个问题是,对单个元素和多个重复元素的处理结果不一致,就会导致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,注意与上面的结果的区别:
"grep" fullname="Gary R Epstein" />
"stty" fullname="Simon T Tyson">
"12345"/>
This is a test.
$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,可见它们是多么常用了。
例如:
始终将testcases作为array; 将testcases下的retries作为testcases中的key;
my $ref_hash_result = XMLin($result_xml,
ForceArray => ["testcases"],
KeyAttr => {"testcases" => "retries"},
);