hspinetでJSONをいじる
HSP3.3からhspinetにjsonを読み書きする機能が追加されました。解説があまりネット上で見つからなかったので調べて書いてみます。パースするJsonは以下のような形式です。
{ "Data": { "value": 3, "str": "Hello", "info": [ {"id": 1, "name": "Alice"}, {"id": 2, "name": "Millia"} ] } }
これをツリー構造で表すと以下のようになります。HSPのマニュアルではこのツリー構造をオブジェクトとよんでいるみたいです。つまりオブジェクトを取得するというのは全体の木のうちの一部(部分木)を取得すると読みかえられます。
HSPでこれをパースするためにはまずJSONオブジェクトを開かなくてはいけません。
notesel JsonData noteload "test.json" //文字列からJsonオブジェクト生成 jsonopen JsonPtr,JsonData
jsonopenが実行された時点でJsonPtrにはJsonオブジェクトのRootのポインタが代入されます。どうやらこのポインタ(たぶんハンドラといったほうが近い)は自分のひとつ下の階層の要素しか参照できないようです。そこでまずRootからDataの階層に下りなくてはいけません。階層を下る(正確には部分木を得る)にはjsongetobjを利用します。
//JsonPtrにDataの階層のポインタが代入される jsongetobj JsonPtr,"Data",JsonPtr jsongeti Value,"value",JsonPtr jsongets String,"str",JsonPtr mes strf("Value:%d,str%s",Value,String)
Dataの階層に移動した後はvalueやstrは自分の直下の階層ということになるのでjsongetsなどを利用して値を得ます。
info以下ですがこちらは配列なので工夫が必要です。HSPではJSONの配列にインデックスでAccessする方方が提供されていないのでイテレータ的な雰囲気でwhileでまわして取得します。また、名前があるわけではないのでjsongetobjではなくjsonnextで配列以下の部分木を取得する必要があります。以下サンプル
//infoの階層に移動 jsongetobj InfoPtr,"info",JsonPtr jsonnext InfoPtr,InfoPtr,2 while(InfoPtr!=NULL) jsongeti ID,"id",InfoPtr jsongets Name,"name",InfoPtr mes strf("ID:%d 名前:%s",ID,Name) //Nextが存在しないとInfoにNULLが返る jsonnext InfoPtr,InfoPtr,0 wend
以上をまとめると以下のようなscriptになります。
#include "hspinet.as" //0をNULLと定数宣言 #const NULL 0 notesel JsonData noteload "test.json" //文字列からJsonオブジェクト生成 jsonopen JsonPtr,JsonData jsongetobj JsonPtr,"Data",JsonPtr jsongeti Value,"value",JsonPtr jsongets String,"str",JsonPtr mes strf("Value:%d,str%s",Value,String) jsongetobj InfoPtr,"info",JsonPtr jsonnext InfoPtr,InfoPtr,2 while(InfoPtr!=NULL) jsongeti ID,"id",InfoPtr jsongets Name,"name",InfoPtr mes strf("ID:%d 名前:%s",ID,Name) //Nextが存在しないとInfoにNULLが返る jsonnext InfoPtr,InfoPtr,0 wend //JSONオブジェクト開放 jsonclose