XML::TreePPを使ってみる

XMLファイルを読み込んで内容を表示する。
ソースコード

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ファイル(sample.xml)

<?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にしておく必要がある。