For Development HEAD DRAFTSearch (procedure/syntax/module):

12.49 rfc.json - JSONのパーズと構築

Module: rfc.json

RFC7159で規定される、JSON形式をパーズしてS式に直す手続きと、 S式をJSON形式に変換する手続きが提供されます。

JSONのパーズ

Condition type: <json-parse-error>

{rfc.json} パーズ手続きparse-jsonparse-json-stringは、 無効なJSON構文に出会った時にこのコンディションを投げます。 <error>を継承し、次のスロットを追加で持ちます。

Instance Variable of <json-parse-error>: position

エラーが起きた入力位置(文字数)。

Parameter: json-nesting-depth-limit

[SRFI-180]{rfc.json} このパラメータの値は実数でなければなりません。 parse-jsonがパーズするJSONテキストに許される最大のネストの深さを指定します。 入力のネスト深さがこのパラメータの値を越えた場合、<json-parse-error>が 投げられます。 デフォルトは+inf.0です。

Function: parse-json :optional input-port

{rfc.json} JSON表記をinput-port (省略された場合はcurrent-input-port)から 読み込みパーズして、結果をS式で返します。 パーズエラーが起きたり、ネストレベルがjson-nesting-depth-limitの 値を超過した場合は<json-parse-error>コンディションを投げます。

下のテーブルに、JSONのデータ型がどのようにSchemeにマップされるかを示します。

true, false, null

シンボルtrue, false and null。 (json-special-handlerで変更可能)

配列

Schemeのベクタ。 (json-array-handlerで変更可能)

オブジェクト

Schemeの連想リスト。キーは文字列で、値はSchemeオブジェクト。 (json-object-handlerで変更可能)

数値

Schemeの非正確な実数。

文字列

Schemeの文字列。

parse-json内で使っているパーザは文字の先読みを行う可能性があるので、 parse-jsonが戻って来た時点で、パーズされたJSON式以降のいくつかの文字が portから既に読まれてしまっている可能性があります。 すなわち、複数のJSON式を読み出すのに、portに対してparse-json を繰り返し呼び出すのはうまくいきません。複数のJSON式をパーズしたい場合は parse-json*を使ってください。

Function: parse-json* :optional input-port

{rfc.json} input-portから、EOFに達するまでJSON式を繰り返し読み取り、 パーズ結果をリストにして返します。

Function: parse-json-string str

{rfc.json} 文字列strをJSONとしてパーズし、結果をS式で返します。 パーズエラーが起きた場合は<json-parse-error>コンディションを投げます。

JSONのデータ型とSchemeの型とのマッピングについては上のparse-json を参照してください。

Parameter: json-array-handler
Parameter: json-object-handler
Parameter: json-special-handler

{rfc.json} これらのパラメータの値は、引数をひとつ取る手続きでなければなりません。 json-array-handlerの値の手続きに渡される引数は、 JSON配列の要素のリストです。 json-object-handlerでは JSONオブジェクトのキーと値をconsしたもののリスト、 json-special-handlerでは シンボルfalse, true, nullのいずれかです。

parse-jsonはJSON配列やオブジェクト、false、true、nullに 出会う度に、 このパラメータの値の手続きを起動して、JSONに対応するSchemeオブジェクトを 得ます。

これらのパラメータのデフォルト値はそれぞれlist->objectidentityidentityです。

次の例では、JSONオブジェクトをハッシュテーブルに変換しています。

(parameterize ([json-object-handler (cut alist->hash-table <> 'string=?)])
  (parse-json-string "{\"a\":1, \"b\":2}"))
 ⇒ #<hash-table ...>

JSONの構築

Condition type: <json-construct-error>

{rfc.json} construct-jsonconstruct-json-stringは、 JSONに変換できないSchemeオブジェクトを見つけるとこのコンディションを投げます。 <error>を継承し、次のスロットを追加で持ちます。

Instance Variable of <json-construct-error>: object

JSON表現に変換できなかったSchemeオブジェクト。

Class: <json-mixin>

{rfc.json} このmixinクラスを継承しているクラスのインスタンスは、以下の規則を使って 自動的にJSONオブジェクトにシリアライズされます。

  • オブジェクトのスロットのうち、:json-nameがそのスロット定義オプション に含まれていて偽でないもののみがシリアライズの対象となります。
  • :json-nameスロット定義オプションが#tならばスロット名が キーとして使われ、そうでなければその値をx->stringで文字列化したものがキー として使われます。
  • スロットの値が再帰的にシリアライズされます。
(define-class <foo> (<json-mixin>)
  ((slot-1 :init-keyword :slot-1 :json-name "Slot1")
   (slot-2 :init-keyword :slot-2 :json-name #t)
   (slot-3 :init-keyword :slot-3)))

(construct-json
  (make <foo> :slot-1 "xyz" :slot-2 123 :slot-3 'abc))
 ⇒ prints
 {"Slot1":"xyz","slot-2":123}
Function: construct-json obj :optional output-port
Function: construct-json-string obj

{rfc.json} SchemeオブジェクトobjのJSON表現を作ります。 construct-jsonは結果をoutput-portに書き出します。デフォルトは current-output-portです。construct-json-stringは結果を文字列で返します。

objがJSONにマップできないオブジェクトを含んでいた場合は <json-construct-error>コンディションが投げられます。

Schemeオブジェクトは以下のようにJSONへと変換されます。

シンボルfalse, #f

false

シンボルtrue, #t

true

シンボルnull

null

リスト、 <dictionary>のインスタンス

JSONオブジェクト (リストはキーと値の連想リストでなければならない)

文字列

文字列

実数

数値

<sequence>のインスタンス (文字列とリストを除く)

JSON配列



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT