TopProgramming LanguagePerl > XML::Simpleで取得したデータが引き起こす文字化けの対処方法
2010年6月18日

XML::Simpleで取得したデータが引き起こす文字化けの対処方法

Posted at June 18,2010 1:55 AM
Category:[Perl]
Tag:[]

XML::Simpleを使ったPerlスクリプトの文字化けではまってしまったので、その備忘録です。

1.発生事象

Perlスクリプトで次のXMLファイルを読み込みます。ファイルの文字コードはUTF-8です。

<?xml version="1.0" encoding="utf-8"?>
<list>
<name>ほげ</name>
</list>

Perlスクリプト(CGI)のサンプルは次の通りです。ファイルの文字コードはUTF-8です。

#!/usr/bin/perl
 
use strict;
 
use CGI;
use XML::Simple;
 
my $q = new CGI;
print $q->header(-charset=>'utf-8');
print $q->start_html;
 
my $xml = XMLin('foo.xml');
my $name = $xml->{name};
 
print <<EOF;
<form method="post" action="hoge.cgi">
名前:<input type="text" id="hoge" name="hoge" value="$name" />
<input type="submit" name="submit" value="送信" />
</form>
EOF
 
print $q->end_html;

このCGIをブラウザで表示すると、次のように、スクリプトに記述した全角文字の文字化けが発生します。

文字化けが発生

XMLファイルから取得する文字が、次のように全角文字でなければ文字化けは発生しません。

<?xml version="1.0" encoding="utf-8"?>
<list>
<name>hoge</name>
</list>

文字化けが発生しない

2.原因

XMLinで日本語を含む文字列を取得する場合、XML宣言のencoding属性に指定した文字コードの内部文字列に変換されます。よって外部に出力する場合、バイト文字列に変換(エンコード)する必要があるようです。

Data::Dumperで$nameを出力すると、「ほげ」は次のようになっていました。

$VAR1 = "\x{307b}\x{3052}";

試しに、次のようなサンプルであれば、

my $name = 'ほげ';

Data::Dumperで$nameを出力すると、

$VAR1 = 'ほげ';

となりました。

推測ですが、文字化けが発生したのは、内部文字列とバイト文字列が混在していたため、Perl自体がバイト文字列である「名前」「送信」をさらにエンコードを行い、文字化けが発生したものと思われます(解釈が間違っていたらご指摘ください)。

3.対処

スクリプトの$nameをUTF-8にエンコードすることで解決しました。

#!/usr/bin/perl
 
use strict;
 
use CGI;
use XML::Simple;
use Encode;
 
my $q = new CGI;
print $q->header(-charset=>'utf-8');
print $q->start_html;
 
my $xml = XMLin('foo.xml');
my $name = encode('UTF-8', $xml->{name});
 
print <<EOF;
<form method="post" action="hoge.cgi">
名前:<input type="text" id="hoge" name="hoge" value="$name" />
<input type="submit" name="submit" value="送信" />
</form>
EOF
 
print $q->end_html;

文字化けが発生しない

4.その他

出力時だけでなく、スクリプトに記述した全角文字と比較をする際も、予めエンコードしておく必要があります。

my $name = encode('UTF-8', $xml->{name});
if ($name eq 'ほげ') { ... }

以上です。色々調べてこれが最適解と思ったのですが、より適切な解決方法がありましたらコメントください。

2010.6.18 追記
下記の記事で、utf8プラグマの情報頂きました。ありがとうございました。

日曜プログラマのそゞろ事 - XML::Simpleで文字化けしない方法

5.参考サイト

参考サイトは下記です。ありがとうございました。

サンプルコードによるPerl入門 - XML::Simple - シンプルなXMLパーサ / Perlモジュール徹底解説
Posted by yujiro   このページの先頭に戻る
関連記事
この記事を読んだ人はこんな記事も読んでいます
人気エントリー
Hatena Hot Entries
Hatena Entries
トラックバックURL


トラックバック

XML::Simpleで文字化けしない方法 from 日曜プログラマのそゞろ事
普段、MovableTypeのプラグインでお世話になっている「小粋空間」さんが、... [続きを読む]

Tracked on June 18, 2010 11:05 PM
コメント

utf8 フラグあたりはなかなか理解しにくいところですが、このあたりが参考になるかもしれません。
http://wiki.bayashi.net/perl/unicode
http://blog.livedoor.jp/dankogai/archives/51031595.html
http://d.hatena.ne.jp/tokuhirom/20080408/1207619640
http://blog.livedoor.jp/dankogai/archives/51290188.html

それでも足りない場合は 'perl utf8 flag' でぐぐると幸せになれるかも。

問題ないように追記するとこうなるのかなぁ。
http://codepad.org/g3Rkgelf

[1] Posted by punitan logo : June 18, 2010 10:36 PM
コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字 イタリック アンダーライン ハイパーリンク 引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)

Now loading...
Introduction
Entry Trackbacks
XML::Simpleで文字化けしない方法
 [日曜プログラマのそゞろ事] 06/18 23:05
Entries of this Category
Recent Entries
Recent Comments
Recent Trackbacks
QRcode

現在停止中です
携帯電話からこのQRcodeを撮影することで携帯用URLを取得することができます

URI for cellular phones
ギターに入った猫
Styles
Font Size
Default
For defective color vision
Gray Scale
RGB Color
Search this site

このブログをメールで購読する by:FeedBurner

loading ...
Categories
Monthly Archives
BlogPeople
Syndicate this site
FeedBurner(RSS1.0/RSS2.0/Atom)
Counter
これまでのアクセス
クリエイティブ・コモンズ・ライセンス
Powered by
Movable Type 5.12