JSON Pointer とは
JSON Pointer は、Jsonドキュメント内の特定の値へのパスを定義する文字列構文です。
大まかに言えば、ルートからのプロパティを /
で連結してパスを構築します。
以下の Jsonドキュメントが有った場合、
{ "name": "some product", "price": 10.5, "features": [ "easy to use", { "name": "environment friendly", "url": "http://example.com" } ], "k\"l": 6, "a/b": "a" }
/name
と指定すれば some product
を指し示します。
主に、JSON Patch(RFC 6902) での変更ポイントを指定するために使われます。
JSON Pointer の構文
JSON Pointer は常に /
から始まり、ルートからの絶対パスを指定します。
JSON Pointer として空文字を指定した場合には、対象のJSONドキュメント全体を指します。
JSON Pointer の ABNF シンタックスは以下のようになっています。
json-pointer = *( "/" reference-token ) reference-token = *( unescaped / escaped ) unescaped = %x00-2E / %x30-7D / %x7F-10FFFF ; %x2F ('/') and %x7E ('~') are excluded from 'unescaped' escaped = "~" ( "0" / "1" ) ; representing '~' and '/', respectively
JSON Pointer が存在しない要素を指す場合にはエラーと評価されます。
JSON Pointer のエスケープ
プロパティ名に ~
が含まれている場合、~0
のようにエスケープし、プロパティ名に /
が含まれている場合、~1
のようにエスケープする必要があります。
よって、上記 JSON ドキュメントの最後の要素は、 JSON Pointer では /a~1b
と表します。
なお、~01
のデコードは ~1
であり、/
ではありません。
文字列のエスケープは通常のJSONと同様に、"
(%x22), \
(%x5C), 及び %x00-1F の制御コードはバックスラッシュでエスケープとなります。
上記 JSON ドキュメントでは、k\"l
というJSON Pointer で 6
を指します。
また、URIフラグメント識別子の表現も許可されています(フラグメントルールで許可されていない文字はパーセントエンコード)。
上記 JSON ドキュメントでは、#/k%22l
という JSON Pointer で 6
を指します。
http://example.com/schema.json#/k%22l
のようにアクセスすることになります。
JSON 配列の指定
参照先がJSON配列の場合には、配列要素をゼロベースのインデックスで指定します。
前述のJSONオブジェクトを例にすれば以下のようになります。
/features/0
easy to use
/features/1/url
http://example.com
/features/-
と指定した場合には、配列の最後の要素の後ろを指定します。
これは主に、JSON Patch で要素を追加する場合に使用します。
配列インデックスの ABNF構文は以下のようになっています。
array-index = %x30 / ( %x31-39 *(%x30-39) ) ; "0", or digits without a leading "0"
Relative JSON Pointer
RFC として定義されてはいませんが、絶対パスで指定する JSON Pointer に対して、相対パスを指定する Relative JSON Pointer もあります。
Relative JSON Pointer の ABNF シンタックスは以下のようになっています。
relative-json-pointer = non-negative-integer <json-pointer> relative-json-pointer =/ non-negative-integer "#" non-negative-integer = %x30 / %x31-39 *( %x30-39 ) ; "0", or digits without a leading "0"
Relative JSON Pointer では現在の位置を 0
で指定し、1
で1つ上の親、2
で2つ上の親を指定します。
親の指定以降は、JSON Pointer と同じ書式で、要素を下っていきます。
Relative JSON Pointer では #
で、現在の位置のプロパティ名、配列の場合にはインデックスを表します。
前述と同様の、以下のJSONドキュメントにて、
{ "name": "some product", "price": 10.5, "features": [ "easy to use", { "name": "environment friendly", "url": "http://example.com" } ], "k\"l": 6, "a/b": "a" }
現在の位置が http://example.com
を指す場合(JSON Pointer における/features/1/url
)、現在位置からの相対ポインタとして以下のようになります。
0
->http://example.com
0#
->url
1#
-> 1(配列インデックス)1/name
->environment friendly
2#
->features
2/0
->easy to use
2/0#
-> 0(配列インデックス)3
-> ドキュメント全体(ルート)