XPagesでJSONをパースしよう、 fromJson関数の使い方
今更聞けないJSONって何?
JSON(ジェイソン、JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptにおけるオブジェクトの表記法をベースとしているが、JSONはJavaScript専用のデータ形式では決してなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しに使えるよう設計されている。
引用:Wikipedia
論より証拠。 JSONってこんな形式です。
[ { "勇者": [ "隼の剣", "光の鎧" ] }, { "格闘家": [ "鉄の爪" ] }, { "魔法使い": [ "いかづちの杖", "水の羽衣" ] } ]
Javascriptのオブジェクトの表記法と配列を組み合わせてとってもシンプルにデータ格納してしまおうということですね。正直、開発者にとってはXMLよりJSONのほうが好きな人のほうがおおいんじゃないでしょうか。
さて、ここから本題です。
XPagesのサーバーサイドJavascriptでJSONをパースするには
SSJSってサーバーで動くJavascriptだよね、だったらJSONもJavascriptのフォーマットだし扱い得意だよね、と当然思う方も多いと思います。
実際、XPagesではJSONをパースさせるのに幾つか方法があるようです。
- eval() 関数を使う。 XPagesの標準関数であるeval()を使ってお手軽にパースすることができます。こちらの例ではビューのカラムに表示させるコンテンツを文書毎にもつJSONのフィールドから一度パースして表示させています。 中々軽量でいいと思います。
- XPagesに標準で実装されているランタイムライブラリ、com.ibm.commons.util.io.json を使う。これはほぼJavaよりのソリューションになりますが、JsonJavaFactory、JsonParser、Iterator 等を使いパースしていきます。 より高度なJSONデータを扱う必要がある場合には適していると思います。例はこちら
- fromJson() 関数を使う。なんとXPagesには標準でfromJson() 関数なるものが存在していました。 これを使えば簡単にSSJSでJSONをあつかえるようになります。
今回は(3)のfromJson() 関数の扱い方について書いてみます。
Domino Designerのヘルプに乗ってない !?
まずこの関数ですが、Domino Designer (バージョン9時点)のヘルプに載ってません。 もう一つJson形式のObjectを文字列に変えるtoJson() 関数も用意されていますが、どちらも載っていません。
Domino DesignerのSSJSの補完機能を見る限り、
fromJson(str:string) any
となり、 strのパラメーターにJSONフォーマットに則した文字列を渡してやると、Javascript Object形式で値が帰ってきます。
Objectから以下のように値を参照できます。
var strJsonSimple:String = '{"name":"apple","color":"red","num":"10"}';
var jsonObjSimple = fromJson(strJsonSimple);
return jsonObjSimple.name;
しかし、この場合(青文字の部分)はObjectに"name"という変数(属性?)があるということを前提にプログラミングされています。
実際は、JSON文字列がObjectになった後、変数もその値もわからないこともあると思います。
その場合、Javascriptでfor-in文による繰り返しで回してやれば値の取得が可能になります。
例として、冒頭で上げたJSONをXPagesでパースして表示しているサンプルを掲載します。 Objectに配列を持つという組み合わされた構造のJSONを以下のようにパースしています。
var strRet:String = ""; var strJson:String = '[{"勇者": ["隼の剣","光の鎧"]},{"格闘家": ["鉄の爪"]},{"魔法使い": ["いかづちの杖","水の羽衣"]}]'; var jsonObj = fromJson(strJson); for(var char_num in jsonObj){ var charEntry = jsonObj[char_num]; for(var char_name in charEntry){ strRet += "キャラクター"+char_num+": "+ char_name +" "; var charEquipment = charEntry[char_name]; var equipments = @Explode(charEquipment, ","); for (var k = 0; k < equipments.length; k++){ strRet += " 装備"+(k+1)+" = "+equipments[k]+" "; } } } return strRet;
計算結果フィールドに入れた結果はこんな感じです。