XMLと私
というわけで、設定ファイルや何やらでXMLを使っていたり、サーバとの連携でXMLしか返さないAPIを叩いている開発者はまだそれなりにいると思います。中には返されるXMLが正しくパースできない形式なのでクライアント側で修正するなど涙ぐましいコードをコミットして血潮を沸かせている人もいるに違いありません(実体験)。
Appceleratorのトレーニングでも、サーバとの連携ではJSON形式のデータでやり取りすることが推奨されています。理由は、JavaScriptなのでそのままパースして利用できることに加えて、XMLと比較してやり取りするデータのペイロードが少なくて済むからです。
とはいえ、既存のAPIサーバがJSONに対応していなければ綺麗事はいってられないのも事実。TitaniumにもXMLを扱う機能は用意されており、ものすごく頑張ればSOAPも利用できるのですが、出来ることなら避けたいところ。
変換しちゃおう
そこで、クライアント側でXMLをJSONに変換して利用する方法を検討してみました。まず最初にNode.jsの状況を確認したところ、xml2jsというパッケージがポピュラーなようです。ざっと確認したところ、でもこのままではTitanium上では利用できません。
そこで、ブラウザで利用するためにビルド済みのJSファイルがあったのでこちらを使ってみました。requireから呼び出せるように末尾に
module.exports = xml2json;
一行だけ追記しておきます。使い方はこちらの通り。以下、app/assets/直下にtest.xmlというファイルが存在する前提で書いています。
var xml2json = require('xml2json');
var file = Ti.Filesystem.resourcesDirectory + 'test.xml';
var xmlString = Ti.Filesystem.getFile(file).read().toString();
Ti.API.info(xml2json.parser(xmlString));
これで動作します。簡単ですね。
簡単ですよ。
ええ。
ライセンスさえ無視すれば、ね。
そうなんです、このxml2jsonライブラリはGPL V.2で公開されているので、この使い方だとソースコードを公開する必要がありそうですね。実際どうなのか確認したことはないのですが、法務部に確認したしと思へども個人事業主だから法務部とかないし、せめては新しき背廣をきてきままなる旅にいでてみん(萩原朔太郎)じゃなかった、GPLの精神は尊重しましょう。
他のライセンスで再挑戦
言葉にできない悲しい事情からソースコードを公開できない場合は、また別の解決方法を探す必要があります。そこでもうちょっと検索したら、なんだ@hamasyou作のこんなのがあるじゃないか。
手元のテストファイルでは大丈夫だったので、これをrequireできるようにします。しました。こちらに置きました。
末尾に以下を追記しただけです。
function xml2json(dom){
var parser = new com.hamasyou.XML.TiDomParser();
return parser.dom2Json(dom.documentElement);
}
module.exports = xml2json;
使い方はいたって簡単、requireしてTitaniumのXMLオブジェクトを渡すだけ。
var xml2json = require('xml2json');
var file = Ti.Filesystem.resourcesDirectory + 'test.xml';
var xmlString = Ti.Filesystem.getFile(file).read().toString();
var xml = Ti.XML.parseString(xmlString);
Ti.API.info(xml2json(xml));
こちらは元々Artistic licenseなのでプロプライエタリなプロダクトでの再利用も問題ありません。
その他のやり方
他にも既存のXML => JSONライブラリをWebViewとevalで呼び出す方法もありますが、その時は改行に注意しましょう。
var file = Ti.Filesystem.resourcesDirectory + 'test.xml';
var xmlString = Ti.Filesystem.getFile(file).read().toString();
$.webview.addEventListener('load', function(e){
var data = $.webview.evalJS('xml2json("'+xmlString.replace(/[\r\n]/g, '')+'");');
});