Home > Perl > XML::Simple の使い方

XML::Simple の使い方

  • 2004-04-09 (金)
  • Perl
  • このエントリーを含むはてなブックマーク

search.cpan.org XML::Simple
↑基本的な使い方はCPANにすべて記載されてます(当たり前)。
ですので作者本人も触れていない、「日本語を含んだXML」をXML::Simpleで取り扱う際のポイントをココで紹介してみようかと思います (仕事で使う際にbashi本人が調べて気づいた事のみになりますが)。

※文字コード「EUC-JP」または「SHIFT_JIS」の日本語を扱う場合のみ下記指摘は該当します。「UTF8」の日本語文字のみ使用している場合は問題無いように見えます。

Perl → XML

use XML::Simple;

my $p = {
  bronze => {
    dragon  => "shiryu",
    pegasus => "seiya", 
    phoenix => "ikki"
  }
};

my $x = new XML::Simple;
my $xml = $x->XMLout($p,NoAttr=>1);
print $xml;

[結果]

<opt>
  <bronze>
    <dragon>shiryu</dragon>
    <pegasus>seiya</pegasus>
    <phoenix>ikki</phoenix>
  </bronze>
</opt>

というのが基本的な使い方ですが、ここでポイントとなるのが XMLout メソッドによって作成されたXML文書の冒頭部分に

<?xml version="1.0" encoding="euc-jp" ?>

↑このようなXMLヘッダタグ(正式名称なんていうの?)がついていない点です。documentを読む限り、XMLout メソッド用に「XMLヘッダタグを先頭に含ませる」オプションは存在しないようです。 まぁ、同じXML::Simpleを使ってこのXMLを取り込む分には問題なさそうですが(実際作者は "問題無い" とコメント書いてます)、「日本語を含んだXML」になると話が違ってきます。

use XML::Simple;

my $p = {
  bronze => {
    dragon  => "紫龍",
    pegasus => "星矢", 
    phoenix => "一輝"
  }
};

my $x = new XML::Simple;
my $xml = $x->XMLout($p,NoAttr=>1);

# ### $xmlの中身 ###
#
# <opt>
#   <bronze>
#     <dragon>紫龍</dragon>
#     <pegasus>星矢</pegasus>
#     <phoenix>一輝</phoenix>
#   </bronze>
# </opt>

# ### ↑このXMLを取り込んでみる ###

my $x = new XML::Simple;
my $p = $x->XMLin($xml);

[結果]

not well-formed (invalid token) at line 4, column 12, byte 30 
at /usr/lib/perl5/site_perl/5.6.1/i386-linux/XML/Parser.pm line 187

なにが起きたかというと、
本来ならXMLヘッダタグに記述されている「文字コード」指定が存在しないので、
→XMLin メソッドからコールされる XML::Parser がすべての文字をデフォルト文字コードの「UTF8」として解釈しようする
→予期しない「EUC-JP」「SHIFT_JIS」の文字を読み取ろうとする
→エラー
というわけです(あくまでもbashi想像 /w)。

ですので(後にXMLin等でPERLに取り込む予定の)日本語を含んだXMLを作成する場合は、自分でXMLヘッダタグをつけておく必要があります。

use XML::Simple

my $p = {
  bronze => {
    dragon  => "紫龍",
    pegasus => "星矢", 
    phoenix => "一輝"
  }
};

my $encoding = "euc-jp";  # or "Shift_JIS";

my $x = new XML::Simple;
my $xml = $x->XMLout($p,NoAttr=>1);
my $head = qq(<?xml version="1.0" encoding="${encoding}" ?>\n);
$xml = $head . $xml;
print $xml;

[結果]

<?xml version="1.0" encoding="euc-jp" ?>
<opt>
  <bronze>
    <dragon>紫龍</dragon>
    <pegasus>星矢</pegasus>
    <phoenix>一輝</phoenix>
  </bronze>
</opt>

これでバッチリ。XML::Simple でもXML::Parser でもガンガン取り込めます。
しかし無事XMLinを用いてXML文書をPerl構造体に変換できた後も1点注意すべきポイントがあります。 ... 長くなってきたので続きは次のエントリで。
次回: ■XML → Perl

関連情報

XML::Simple は遅い説における意外な落とし穴
XML::Simple は遅い説における意外な落とし穴 - おまけ編

Comments:0

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Home > Perl > XML::Simple の使い方

Search
Feeds

Page Top