XPRIM_JsonObject と XPRIM_JsonArray は、JSON オブジェクトと JSON アレイのメモリ内表記です。それぞれの子エレメントはメモリ内のツリー状構造に格納され、メンバ名やアレイ・インデックスによるエレメントへのランダム・アクセスをサポートします。XPRIM_JsonObject と XPRIM_JsonArray には共通のスーパークラス XPRIM_JsonElement があります。
XPRIM_JsonObject/XPRIM_JsonArray はどちらも読み込み可能で (ランダム・アクセスにより) 変更も可能なので、別のルーチンやサードパーティのライブラリ・ルーチンに引き渡すためにメモリ内に自身の JSON データの抽象表記を作成する必要がある時には便利です。
ただし、JSON 文字列 (つまり、JSON データを示す文字列) を構築するだけの場合は、代わりに XPRIM_JsonWriter を使用してください。XPRIM_JsonWriter は JSON 文字列の構築のために特別に設計されたものなので、メモリのフットプリントも最小で非常に効率的です。同様に、JSON 文字列を解析してその値を読み込む必要がある場合は、XPRIM_RandomAccessJsonReader または XPRIM_JsonReader を使用する方が効果的です。XPRIM_JsonWriter と XPRIM_JsonReader については、次のセクションで説明します。
以下は、XPRIM_JsonObject と XPRIM_JsonArray の作成方法を示しています。
Define_Com Class(#XPRIM_JsonObject) Name(#RootObject)
Define_Com Class(#XPRIM_JsonArray) Name(#JsonArray)
これで、自身の JSON オブジェクトや JSON アレイに値を入れていくことができます。
JSON データには、次の 6 つの値のタイプがあります。
XPRIM_JsonObject と XPRIM_JsonArray には、オブジェクトまたはアレイに挿入する値のタイプそれぞれに対応する、以下のようなメソッドがあります。
ただし、XPRIM_JsonObject の Insert メソッドには挿入する値のプロパティ名を指定する Key パラメータがありますが、XPRIM_JsonArray の Insert メソッドではアレイの最後に値が追加されるため Key パラメータはないことに注意してください。
例:
* 文字列 "John" を JSON オブジェクトの "name" プロパティとして挿入
#RootObject.InsertString Key('name') String('John')
* JSON アレイに番号 9 を挿入
#JsonArray.InsertNumber Number(9)
* NULL 値を JSON オブジェクトの "allergies"プロパティとして挿入
#RootObject.InsertNull Key('allergies')
次の例は別のオブジェクトのプロパティとしてのオブジェクト/アレイの作成方法です。
* XPRIM_JsonObject 参照を定義
Define_Com Class(#XPRIM_JsonObject) Name(#ChildObject)
* 住所の street (番地) と suburb (市町村) を #ChildObject に挿入
#ChildObject.InsertString Key('street') String('122 Arthur St')
#ChildObject.InsertString Key('suburb') String('North Sydney')
* #ChildObject を "address" という名前のメンバとして #RootObject に挿入
#RootObject.InsertElement Key('address') Element(#ChildObject)
XPRIM_JsonObject (または XPRIM_JsonArray) を (デバッグ用などの用途で) 文字列に変換する場合は、SerializeAsString メソッドを呼び出します。
Define_Com Class(#PRIM_DC.UnicodeString) Name(#MyJsonString)
* JSON を文字列に変換
#MyJsonString := #RootObject.SerializeAsString
SerializeToFile を利用して、JSON オブジェクト (またはアレイ) をファイルにシリアル化することもできます。
#RootObject.SerializeToFile Path('/home/TestJson.txt')
ParseString や ParseFile メソッドを利用して、JSON 文字列を解析し、JSON 文字列から XPRIM_JsonObject や XPRIM_JsonArray を構築することもできます。
* エラー詳細を保持するための ErrorInfo オブジェクトを定義
Define_Com Class(#XPRIM_ErrorInfo) Name(#ErrorInfo)
* 'Parse' メソッドを呼び出し
#RootObject.ParseString String(#JsonString) ErrorInfo(#ErrorInfo)
* 解析が失敗した場合、エラー・メッセージを取得
If (*Not #ErrorInfo.OK)
#ErrorMessage := #ErrorInfo.ErrorMessage
EndIf
次の Get… アクセサー・メソッドのいずれか 1 つを使用して、オブジェクトやアレイの値にアクセスすることができます。
例えば、'#String' という名前の変数に格納された次のような JSON 文字列がある場合、
{
"name":
{
"given":"John",
"surname":"Smith"
},
"age":45,
"contactNo":
[
{ area:"02", no:"9378 2867", type:"landline" },
{ no:"0468 732 371", type:"mobile" }
]
}
以下のようにして、この JSON 文字列を解析し、値を読み込みます。
Define_Com Class(#XPRIM_JsonObject) Name(#RootObject)
Define_Com Class(#XPRIM_ErrorInfo) Name(#ErrorInfo)
* JSON 文字列を解析
#RootObject.ParseString String(#String) ErrorInfo(#ErrorInfo)
* 最初に JSON 文字列の解析に成功したことを確認
If (#ErrorInfo.OK)
* 値を取得
#GivenName := #RootItem.GetObject('name').GetString('given')
#Surname := #RootItem.GetObject('name').GetString('surname')
#Age := #RootItem.GetNumber('age')
Endif
ItemCount プロパティを使うと、含まれるアレイ (またはオブジェクト) の数が分かります。
Define_Com Class(#XPRIM_JsonArray) Name(#ContactNumbers)
* contactNo の値 (アレイ), ... を取得し、
* ... #ContactNumbers に割り当て
#ContactNumbers.Refer To(#RootItem.GetArray('contactNo')
* 'ItemCount' プロパティを使って、アレイ長を取得
#ContactCount := #ContactNumbers.ItemCount
JSON アレイ内のエレメントで繰り返し処理を行うには、以下のように FOR-EACH-IN を利用します。
* この前の例から contactNo アレイを利用
FOR EACH(#Number) IN(#ContactNumbers)
#COM_SELF.ProcessContactNumber Number(#Number)
ENDFOR
JSON 要素 (XPRIM_JsonElement) のタイプは、その Type プロパティを読み込むことで確認できます。戻される値は次のいずれかになります。
JSON 要素が特定のタイプであるかどうかを確認したいだけの場合は、次の Is… のいずれかを利用することができます。