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