【perlメモ】XML::Simpleの使い方。

XMLの解析を行なうときによく使うのがXML::Simpleですが、よく使う方法をメモっておきます。

use XML::Simple;
my $xml = XML::Simple->new();

基本

my $xref = $xml->XMLin([xmlファイル又はxml文字列],[オプション]);

全てを強制的に配列として扱う場合

my $xref = $xml->XMLin($res,ForceArray => 1);

特定の要素のみを強制的に配列として扱う場合

my $xref = $xml->XMLin($res, ForceArray=>[‘area’,’response’]);

要素の内容が空の時に強制的に「”」や「undef」を指定する。

my $xref = $xml->XMLin($res, SuppressEmpty => ”);
my $xref = $xml->XMLin($res, SuppressEmpty => undef);

実際の使用例を以下に示す。


ForceArray => 1の例

以下のXMLをパースしてダンプするプログラムを実行してみると

XML-Simple03.pl

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
{
    no warnings ‘redefine’;
    package Data::Dumper;
    sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;

my $xs = XML::Simple->new();

my $XML1 =<<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<result>
    <item>
        <area_id>1</area_id>
        <area_name>TOKYO</area_name>
    </item>
</result>
EOF

my $ref = $xs->XMLin($XML1);

print Dumper($ref);

下のようになります。

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple03.pl
$VAR1 = {
          ‘item’ => {
                      ‘area_name’ => ‘TOKYO’,
                      ‘area_id’ => 1
                    }
        };

F:\kumacchi\MyProgram\perl\sample\XML-Simple>

次に下のようにitemが二つ以上ある場合のサンプルを実行してみます。

XML-Simple04.pl

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
{
    no warnings ‘redefine’;
    package Data::Dumper;
    sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;

my $xs = XML::Simple->new();

my $XML2 =<<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<result>
    <item>
        <area_id>1</area_id>
        <area_name>TOKYO</area_name>
    </item>
    <item>
        <area_id>2</area_id>
        <area_name>KUMAMOTO</area_name>
    </item>
</result>
EOF

my $ref = $xs->XMLin($XML2);

print Dumper($ref);

結果はこうなります。

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple04.pl
$VAR1 = {
          ‘item’ => [
                      {
                        ‘area_name’ => ‘TOKYO’,
                        ‘area_id’ => 1
                      },
                      {
                        ‘area_name’ => ‘KUMAMOTO’,
                        ‘area_id’ => 2
                      }
                    ]
        };

F:\kumacchi\MyProgram\perl\sample\XML-Simple>

先程のXML-simple03.pl結果を並べてみるとよくわかると思いますがitemが2個以上になると[ ]で囲まれて配列扱いになっているのが分かると思います。

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple03.pl
$VAR1 = {
          ‘item’ => {
                      ‘area_name’ => ‘TOKYO’,
                      ‘area_id’ => 1
                    }
        };

F:\kumacchi\MyProgram\perl\sample\XML-Simple>

XML-Simple03.plの場合はarea_nameにアクセスするには

$ref->{item}->{area_name}

でアクセスすることが出来ますが、

XML-Simple04.plの場合はarea_nameにアクセスするには

$ref->{item}[0]->{area_name}

の様にして配列としてアクセスしなければなりません。

これは動的にXMLの結果が変わるようなRESTの情報を解析する場合要素の数によって配列になったり配列じゃなかったりするのはプログラムが複雑になってしまいます。

要素数が1個しか無いときでも配列にしてしてしまいたい時にForceArray => 1を使います。これで要素が1個の時でも以下の様にして配列のようにアクセスすることが出来るようになります。

$ref->{item}[0]->{area_name}

実際のサンプルです。

XML-Simple05.pl

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
{
    no warnings ‘redefine’;
    package Data::Dumper;
    sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;

my $xs = XML::Simple->new();

my $XML1 =<<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<result>
    <item>
        <area_id>1</area_id>
        <area_name>TOKYO</area_name>
    </item>
</result>
EOF

my $ref = $xs->XMLin($XML1,ForceArray=>1);
print Dumper($ref);

print $ref->{item}[0]->{area_name}[0],"\n";

結果は以下のとおり。

実際には
$ref->{item}[0]->{area_name}
ではなく
$ref->{item}[0]->{area_name}[0]
となってしまった。ダンプの結果を見るとわかるが全ての要素に[ ]が付いているのでそうなる。「ForceArray=>1」はすべての要素を配列にしてしまうのでこうなる。

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple05.pl
$VAR1 = {
          ‘item’ => [
                      {
                        ‘area_name’ => [
                                         ‘TOKYO’
                                       ],
                        ‘area_id’ => [
                                       1
                                     ]
                      }
                    ]
        };
TOKYO

F:\kumacchi\MyProgram\perl\sample\XML-Simple>


ForceArray=>[‘要素’,’要素’]の例

特定の要素だけ配列にしたい場合は
my $ref = $xs->XMLin($XML1,ForceArray=>[‘要素’,’要素’]);
のようにする。
XML-Simple06.pl

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
{
    no warnings ‘redefine’;
    package Data::Dumper;
    sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;

my $xs = XML::Simple->new();

my $XML1 =<<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<result>
    <item>
        <area_id>1</area_id>
        <area_name>TOKYO</area_name>
        <tel>
            <number>111-2222</number>
        </tel>
    </item>
</result>
EOF

my $ref = $xs->XMLin($XML1,ForceArray=>[‘item’,’number’]);
print Dumper($ref);

print $ref->{item}[0]->{area_name},"\n";

結果は以下の通り、指定した要素だけが配列になっているのがわかる。area_nameにも
$ref->{item}[0]->{area_name}
でアクセス出来るようになっている。

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple06.pl
$VAR1 = {
          ‘item’ => [
                      {
                        ‘area_name’ => ‘TOKYO’,
                        ‘tel’ => {
                                   ‘number’ => [
                                                 ‘111-2222’
                                               ]
                                 },
                        ‘area_id’ => 1
                      }
                    ]
        };
TOKYO

F:\kumacchi\MyProgram\perl\sample\XML-Simple>


SuppressEmpty => ”の例

下のサンプルではわざとarea_nameの内容を空にしてある。

XML-Simple07.pl

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
{
    no warnings ‘redefine’;
    package Data::Dumper;
    sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;

my $xs = XML::Simple->new();

my $XML1 =<<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<result>
    <item>
        <area_id>1</area_id>
        <area_name></area_name>
    </item>
</result>
EOF

my $ref = $xs->XMLin($XML1,ForceArray=>[‘item’,’number’]);
print Dumper($ref);

print $ref->{item}[0]->{area_name},"\n";

実行結果は以下の通りであるが、area_nameの内容は空が表示されるのではないかという予想に反してハッシュ値となる。この場合プログラム側ではREF関数などを使ってハッシュ値だったら空文字を代入等の処理をすることになるが面倒なので空なら空文字を返してくださいよという時に、「SuppressEmpty => ”」とオプションを指定すると要素の内容が空の時ハッシュ値ではなく空文字が設定されるようになる。「SuppressEmpty => undef」とするとundefが設定される。これは便利なので覚えておいたほうが良い。

 

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple07.pl
$VAR1 = {
          ‘item’ => [
                      {
                        ‘area_name’ => {},
                        ‘area_id’ => 1
                      }
                    ]
        };
HASH(0x1aa7d44)

F:\kumacchi\MyProgram\perl\sample\XML-Simple>

実際に「SuppressEmpty => ”」を指定したサンプルは以下の通り。

XML-Simple08.pl

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
{
    no warnings ‘redefine’;
    package Data::Dumper;
    sub qquote { return shift; }
}
$Data::Dumper::Useperl = 1;

my $xs = XML::Simple->new();

my $XML1 =<<"EOF";
<?xml version="1.0" encoding="UTF-8"?>
<result>
    <item>
        <area_id>1</area_id>
        <area_name></area_name>
    </item>
</result>
EOF

my $ref = $xs->XMLin($XML1,ForceArray=>[‘item’,’number’],SuppressEmpty => ”);
print Dumper($ref);

print "[$ref->{item}[0]->{area_name}]\n";

実行結果は以下の通り、ハッシュ値ではなく空になっているのがわかる。

F:\kumacchi\MyProgram\perl\sample\XML-Simple>XML-Simple08.pl
$VAR1 = {
          ‘item’ => [
                      {
                        ‘area_name’ => ”,
                        ‘area_id’ => 1
                      }
                    ]
        };
[]

F:\kumacchi\MyProgram\perl\sample\XML-Simple>

 

更に詳しい情報はCPANのページを参照のこと


関連リンク

Browse and search CPAN : XML::Simple
XML::Simple

(Visited 49 times, 1 visits today)

タグ : , ,