『 Shift-JISやEUC-JPのXMLを読み込むSimpleXMLLoaderクラス 』

2009 年 7 月 30 日

先日のエントリ『AS3の標準XMLパーサ ちょっとしたまとめ』で、余計な説明を省くために作ったSimpleXMLLoaderクラスでしたが、使ってみたら予想以上に便利だったのでバージョンアップしてみました。まあ大したことはやっていなくて、今までutf-8専用だったところを、好きな文字コードで書かれたxmlを読み込めるようにしただけです。

» SimpleXMLLoader.as (拡張子をasに変更してください)

例をどうぞ。使い方としては、loadメソッドにオプションとして文字コードを指定できようになっただけで、他は変わっていません。なお、エラー処理付きのサンプルは先日のエントリに載せています。

//Shift-JISで書かれたxmlを読み込む
var loader:SimpleXMLLoader = new SimpleXMLLoader();
loader.onLoadComplete = onLoadComplete;
loader.load("shift-jis.xml", SimpleXMLLoader.SHIFT_JIS);

function onLoadComplete(xml:XML):void {
  trace(xml + "を読み込みました。ね?簡単でしょ?");
}


動作確認済みの4種類の文字コード(左)と、第2引数への指定の仕方(右)を以下に示します。引数省略時はUTF-8で読み込みます。
UTF-8 ・・・ SimpleXMLLoader.UTF_8
Shift-JIS ・・・ SimpleXMLLoader.SHIFT_JIS
EUC-JP ・・・ SimpleXMLLoader.EUC_JP
JIS ・・・ SimpleXMLLoader.JIS

これ以外の文字コードは動作確認していませんが、Adobe ActionScriptリファレンス『サポートする文字セット』の文字コードであれば大丈夫だと思います、多分。

上記リファレンスの文字コードをミスタイプしそうだったり、文字列を直接書くのはどうなのという僕のような人のために、指定文字列をstatic変数化して1にまとめたCharsetクラスを作りました。アラビア語のxmlを読み込むときには、Charset.ASMO_708 を第2引数に指定してください。読み込めるかも知れません。

» Charset.as (拡張子をasに変更してください)

それでは、今回のバージョンアップ箇所まわりの中身がどうなっているのかを軽く解説しておきます。
まずFlashの特性として、検出したテキストを全部Unicodeとして見なしてしまうために、UTF-8以外の2バイト文字は化けてしまいます。
じゃあAS2時代よろしく System.useCodePage = true; すればいいじゃないかと思えば、今度はxmlデータの末尾にゴミが入ったりすることがあります。テキストの中身が組み変わったりすることもあるようで、あまり良くないようです。AS2のときはうまくいってたのに残念です。

結局どうしたのかというと、ByteArrayを使いました。バイナリデータを扱うアレです。ByteArrayには、指定した文字コードのバイナリ列をutf-8へとエンコードしながら読み出すというreadMultiByteメソッドがあるのでこれを使います。そのためには、まずURLLoaderの読み込みデータフォーマットをバイナリで指定しなければなりません。

具体的には、読み込み時には下記のようにURLLoaderクラスのdataFormatプロパティをURLLoaderDataFormat.BINARYで指定します。

var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.load(new URLRequest("shift-jis.xml"));

そして、読み込み完了時に一度データをByteArrayに格納した後にreadMultiByteメソッドでUTF-8として読み取ります。下記の例ではShift-JISからUTF-8へエンコードしながらテキストを読み出しています。実装したコードよりもちょっとだけ丁寧に書いてます。

var ba:ByteArray = loader.data as ByteArray;
var utf8Str:String = ba.readMultiByte(ba.length, "shift-jis");
var xml:XML = new XML(utf8Str);

これでOK。

・・・かと思いきや、このreadMultiByteメソッドもバグ持ちで、EUC-JPを上手く読み込めません。おいおい。。。
そこで、クデラボ -KudeLab-さんが作られたEUC-JP→UTF-8変換ライブラリ『JCode.as』を使わせていただきました。ありがとうございます!

var ba:ByteArray = loader.data as ByteArray;
var utf8Str:String = Jcode.EUCtoUTF8(ba);
var xml:XML = new XML(utf8Str);

最終的な処理の流れとして、ちょっと分岐が不細工なのですが以下のようになりました。
1.UTF-8ならそのままテキストデータとして読み込む
2.EUC-JPならバイナリで読み込んだ後にJCode.asを使ってUTF-8テキストに変換
3.それ以外ならバイナリで読み込んだ後にreadMultiByteメソッドでUTF-8テキストに変換

このプロセスはxml以外のプレーンなテキストの読み込みにも使える話だと思うので、UTF-8以外のテキストを扱いたい方の参考になれば幸いです。

今回のプロジェクト一式はこちらです。
» Download

ちなみに先日のエントリでアップしたのプロジェクト内のSimpleXMLLoaderクラスも最新バージョンににすり替えています。

追記 09.07.31
無駄な処理が紛れていたので修正しました。

//修正前
var ba:ByteArray = new ByteArray();
ba = loader.data as ByteArray;
//修正後
var ba:ByteArray = loader.data as ByteArray;
« 
» 

One Response to “Shift-JISやEUC-JPのXMLを読み込むSimpleXMLLoaderクラス”

  1. [...] ルサイズや回線の重さ?の影響で化け頻度が上がるっぽい) これは使えない・・・。 ↓ SimpleXMLLoaderを使う。 ↓ 成功!! 一応”useCodePage=true”はAS2であればいけるとのこと。でもこれは試 [...]

Leave a Reply