XML::TreePPを使ってみる
use strict; use warnings; use utf8; use IO::File; use XML::TreePP; use Data::Dumper; binmode STDIN, ':utf8'; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; # Input Check if (@ARGV != 1) { print STDERR "Please input XML file name.\n"; exit 1; } my $xmlin_name = $ARGV[0]; # File Check unless (-f $xmlin_name) { print STDERR "$xmlin_name is not found.\n"; exit 1; } # Input XML my $xml_parser = XML::TreePP->new(utf8_flag => 1, use_ixhash => 1); my $xml = $xml_parser->parsefile($xmlin_name); print Dumper($xml); my $persons = $xml->{'addressBook'}{'person'}; # Output XML Data for (my $cnt = 0; $cnt < @$persons; $cnt++) { print '(' . ($cnt + 1) . ')' . "\n"; foreach my $key (keys %{$persons->[$cnt]}) { print "\t" . $key . ' : ' . $persons->[$cnt]{$key} . "\n"; } } exit 0;
<?xml version="1.0" encoding="UTF-8"?> <addressBook> <person> <name>山田 太郎</name> <email>taro.yamada@xxx.com</email> <address>東京</address> </person> <person> <name>田中 次郎</name> <email>jiro.tanaka@xxx.com</email> <address>大阪</address> </person> <person> <name>阿部 三郎</name> <email>saburo.abe@xxx.com</email> <address>名古屋</address> </person> </addressBook>
実行結果(念のため、読み込んだ直後のデータをDumpする。)
$ perl input_xml_treepp.pl sample.xml $VAR1 = { 'addressBook' => { 'person' => [ { 'name' => "\x{5c71}\x{7530} \x{592a}\x{90ce}", 'email' => 'taro.yamada@xxx.com', 'address' => "\x{6771}\x{4eac}" }, { 'name' => "\x{7530}\x{4e2d} \x{6b21}\x{90ce}", 'email' => 'jiro.tanaka@xxx.com', 'address' => "\x{5927}\x{962a}" }, { 'name' => "\x{963f}\x{90e8} \x{4e09}\x{90ce}", 'email' => 'saburo.abe@xxx.com', 'address' => "\x{540d}\x{53e4}\x{5c4b}" } ] } }; (1) name : 山田 太郎 email : taro.yamada@xxx.com address : 東京 (2) name : 田中 次郎 email : jiro.tanaka@xxx.com address : 大阪 (3) name : 阿部 三郎 email : saburo.abe@xxx.com address : 名古屋 $
このモジュールも、XML::LibXML::Simple同様、マップで取得できるのは便利かも知れない。
でも、異なる名前の要素の順番が、そのままでは保持されないのは同じ。
ただ、use_ixhashオプションを1にする事で、マップの順番が保持されるらしい。(Tie::IxHashモジュールが必要)
さらに、utf8エンコードの文字データを取り込むためには、utf8_flagオプションを1にしておく必要がある。