メインコンテンツまでスキップ

1. Introduction (はじめに)

1. Introduction (はじめに)​

JSON [RFC8259] は, 構造化データ値の表現形式として広く使われています. JSONPath は, 与えられた JSON 値の内部から JSON 値を選択し抽出するための文字列構文を定義します.

JSON Pointer [RFC6901] との関係では, JSONPath は置換物ではなく, より強力なコンパニオン (companion) として意図されています. 付録 C を参照してください.

1.1 Terminology (用語)​

本ドキュメント中の "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", "OPTIONAL" というキーワードは, ここに示すとおりすべて大文字で出現する場合に限り, BCP 14 [RFC2119] [RFC8174] に記載されるとおりに解釈されるものとします.

本ドキュメントの文法規則は [RFC5234] に記載されるとおり ABNF として解釈されます. 本ドキュメントにおける ABNF の終端値は UTF-8 エンコーディングではなく Unicode scalar value (Unicode スカラー値) を定義します. 例えば, Unicode の PLACE OF INTEREST SIGN (U+2318) は ABNF では %x2318 と定義されます.

関数は, fname() のように関数名の後に一対の括弧を付けて参照されます.

以下で明確化しない限り [RFC8259] の用語が適用されます. "primitive (プリミティブ)" と "structured (構造化)" という用語は, [RFC8259] の第1節と同様に値の種類をまとめるために用いられます. JSON object (オブジェクト) と array (配列) は構造化され, それ以外の値はすべてプリミティブです. "object", "array", "number", "string" の定義は変更ありません. 特に重要なのは, "object" と "array" が一般的なプログラミング文脈のような汎用的な意味を帯びないことです.

[RFC9485] の用語が適用されます.

本ドキュメントで用いる追加用語を以下に定義します.

Value (値): [RFC8259] に従い, JSON の汎用データモデルに適合するデータ項目, すなわちプリミティブデータ (数値, テキスト文字列, および特別な値 null, true, false), または構造化データ (JSON オブジェクトと配列) です. [RFC8259] は JSON 値のテキスト表現に焦点を当てており, ここで前提とする値の抽象化を完全には定義していません.

Member (メンバ): オブジェクト内の name/value pair (名前と値のペア) です. (メンバ自体は値ではありません.)

Name (名前): メンバを構成する name/value pair における名前 (文字列) です. [RFC8259] でも用いられますが, その仕様は形式的には定義していません. 完全性のためにここに含めます.

Element (要素): JSON 配列内の値です.

Index (インデックス): 配列内の特定の要素を識別する整数です.

Query (クエリ): JSONPath 式の短い呼び名です.

Query Argument (クエリ引数): JSONPath 式が適用される値の短い呼び名です.

Location (位置): クエリ引数内における値の位置です. クエリ引数内のオブジェクトと配列を辿る名前とインデックスの列として捉えることができ, 空列はクエリ引数自身を示します. 位置は Normalized Path (正規化パス, 後述) として表現できます.

Node (ノード): クエリ引数内の位置とともに付随する値の組です.

Root Node (ルートノード): 値がクエリ引数全体である唯一のノードです.

Root Node Identifier (ルートノード識別子): クエリ引数のルートノードを指す式 $ です.

Current Node Identifier (現在ノード識別子): フィルタ式 (後述) の評価の文脈において現在ノードを指す式 @ です.

Children (子, of a node): ノードが配列ならその要素のノード, オブジェクトならそのメンバ値のノードです. ノードが配列でもオブジェクトでもない場合, 子はありません.

Descendants (子孫, of a node): ノードの子, その子の子, 以下再帰的に続くものです. より形式的には, ノード間の "descendants" 関係は "children" 関係の推移閉包です.

Depth (深さ, of a descendant node within a value): 値内におけるそのノードの祖先の数です. 値のルートノードの深さはゼロ, ルートの子は深さ1, その子は深さ2, 以下同様です.

Nodelist (ノードリスト): ノードのリストです. ノードリストは JSON 内で配列などとして表現できますが, 本ドキュメントは特定の表現を要求も仮定もしません.

Parameter (パラメータ): 関数式において関数引数 (実引数) を受け取りうる形式パラメータ (関数の) です.

Normalized Path (正規化パス): 値内のノードを, ちょうどそのノードとなる結果を返すクエリを与えることで識別する JSONPath 式の一形です. クエリ引数内の各ノードは, ちょうど1つの Normalized Path によって識別されます (そのノードに対して Normalized Path が "unique (一意)" であると言います). また特定のクエリ引数に対する Normalized Path であるには, ちょうど1つのノードを識別する必要があります. これは JSON Pointer [RFC6901] に類似しますが構文的には異なります. 注: この定義は第2.7節の構文的定義に基づきます. 値内のノードを識別するがその構文に適合しない JSONPath 式は Normalized Path ではありません.

Unicode Scalar Value: [UNICODE] の code point (コードポイント) のうち high-surrogate と low-surrogate 以外のものです (言い換えれば, 16進で 0 から D7FF または E000 から 10FFFF のいずれかの包含範囲の整数). JSONPath クエリは Unicode スカラー値の列です.

Segment (セグメント): 入力値の子 ([<selectors>]) または子孫 (..[<selectors>]) を選択する構文構造の1つです.

Selector (セレクタ): セグメント内の単一項目で, 入力値を受け取り入力値の子ノードからなるノードリストを生成します.

Singular Query (単一クエリ): ある方法で構文的に制限されたセグメントから構築された JSONPath 式 (第2.3.5.1節) であり, 入力値に関わらず, 式は高々1つのノードを含むノードリストを生成します. 注: 常に単一のノードリストを生成するが第2.3.5.1節の構文に適合しない JSONPath 式は singular query ではありません.

1.1.1 JSON Values as Trees of Nodes (ノードの木としての JSON 値)​

本ドキュメントはクエリ引数を, それぞれが独自のノードを持つ JSON 値の木としてモデル化します. ノードはルートノードか, その子孫のいずれかです.

本ドキュメントは, クエリをクエリ引数に適用した結果をノードリスト (ノードのリスト) としてモデル化します.

ノードはクエリ引数の選択可能な部分です. クエリによってオブジェクトの選択可能な部分はメンバ値のみです. メンバ名とメンバ (名前と値のペア) は選択できません. したがってメンバ値にはノードがありますが, メンバとメンバ名にはありません. 同様に, メンバ値はオブジェクトの子ですが, メンバとメンバ名は子ではありません.

1.2 History (沿革)​

本ドキュメントは Stefan Gössner 氏の広く使われた JSONPath 提案 (2007-02-21 付) [JSONPath-orig] に基づき, その実装の広範な展開から得た経験の上に築かれ, それに対する規範的仕様を提供します.

付録 B では JSONPath が XML の XPath [XPath] にどう触発されたかを述べます.

JSONPath は PHP や JavaScript などのプログラミング言語における JSON 実装の軽量なコンパニオンとして意図されたため, XPath のように独自の式言語を定義する代わりに, クエリの一部を下位ランタイムに委ねました (例: JavaScript の eval() 関数). JSONPath がより多くの環境に実装されるにつれ, JSONPath 式の移植性は低下しました. 例えば正規表現処理はしばしば都合の良い正規表現エンジンに委ねられました.

本ドキュメントはそのような実装依存を取り除き, プログラミング言語や環境を横断して使える共通の JSONPath 仕様となることを目指します. これは後方互換が常に達成されるとは限らないことを意味します. 本ドキュメントの設計原則は, 利用可能で安定した JSON クエリ言語を得るという目的を損なわない限り, 実装間の "consensus (合意)" に従うことです. たとえ粗くてもです.

用語 JSONPath は XPath への触発に加え, クエリの結果が JSON クエリ引数内のノードを識別する paths (パス) の集まりであることから選ばれました.

1.3 JSON Values (JSON 値)​

JSONPath クエリが適用される JSON 値は, 定義上, 妥当な JSON 値です. JSON 値はしばしば JSON テキストを構文解析して構築されます.

JSON テキストを JSON 値へ構文解析すること, および JSON テキストが妥当な JSON を表さない場合に何が起きるかは, 本ドキュメントでは定義しません. [RFC8259] の第4節と第8節は, JSON テキストの文法には適合するが相互運用可能な JSON の用法ではない特定の状況を示しており, 予測不能な振る舞いを引き起こしうるとしています. 本ドキュメントはこれらの状況における JSONPath クエリの予測可能な振る舞いを定義しようとはしません.

特に, 第2.3.1, 2.3.2, 2.3.5, 2.5.2 節の "Semantics" 小節は, 検討対象のオブジェクトの1つについて JSON 値が, 単一オブジェクトに同一メンバ名を共有する複数メンバを含む JSON テキスト ("duplicate names (重複名)", [RFC8259] 第4節参照) から構築された場合に予測不能になる振る舞いを記述します. また名前による子の選択 (第2.3.1節) および文字列の比較 (第2.3.5.2.2節) では, これらの文字列が Unicode スカラー値の列であることを前提とします. そうでない場合振る舞いは予測不能になります ([RFC8259] 第8.2節).

1.4 Overview of JSONPath Expressions (JSONPath 式の概観)​

JSONPath 式は JSON 値, すなわち query argument (クエリ引数) に適用されます. 出力はノードリストです.

JSONPath 式は識別子の後に, それぞれ1つ以上のセレクタを含むゼロ個以上のセグメントの列からなります.

1.4.1 Identifiers (識別子)​

ルートノード識別子 $ はクエリ引数のルートノード, すなわち引数全体を指します.

現在ノード識別子 @ は, フィルタ式の評価の文脈における現在ノードを指します (第2.3.5節).

1.4.2 Segments (セグメント)​

セグメントは入力値の子 ([<selectors>]) または子孫 (..[<selectors>]) を選択します.

セグメントには bracket notation (ブラケット記法) を使えます, 例:

$['store']['book'][0]['title']

より簡潔な dot notation (ドット記法) も使えます, 例:

$.store.book[0].title

ブラケット記法には任意の種類のセレクタを1つ以上 (カンマ区切り) 含みます. セレクタは次節で詳述します.

JSONPath 式はブラケット記法とドット記法を組み合わせてもよいです.

本ドキュメントはブラケット記法を正規形とし, 省略ドット記法をブラケット記法で定義します. 例と説明では便宜上省略形を用います.

1.4.3 Selectors (セレクタ)​

name selector (名前セレクタ), 例: 'name', はオブジェクトの名前付き子を選択します.

index selector (インデックスセレクタ), 例: 3, は配列のインデックス付き子を選択します.

式 [*] では wildcard * (第2.3.2節) がノードのすべての子を選択し, 式 ..[*] ではすべての子孫を選択します.

array slice start:end:step (第2.3.4節) は配列から要素の列を選択し, 開始位置, 終了位置, および開始から終了へ位置を進める任意の step 値を与えます.

フィルタ式 ?<logical-expr> はオブジェクトまたは配列の特定の子を選択します, 例:

$.store.book[[email protected] &lt; 10].title

1.4.4 Summary (要約)​

表1は JSONPath 構文の簡潔な概観を示します.

Syntax Element (構文要素)Description (説明)
$ルートノード識別子 (root node identifier) (第2.2節)
@現在ノード識別子 (current node identifier) (第2.3.5節)
(フィルタセレクタ内でのみ有効)
[<selectors>]子セグメント child segment (第2.5.1節): ノードの
ゼロ個以上の子を選択
.name['name'] の省略形
.*[*] の省略形
..[<selectors>]子孫セグメント descendant segment (第2.5.2節):
ノードのゼロ個以上の子孫を選択
..name..['name'] の省略形
..*..[*] の省略形
'name'名前セレクタ name selector (第2.3.1節): オブジェクトの
名前付き子を選択
*ワイルドカードセレクタ wildcard selector (第2.3.2節): ノードの
すべての子を選択
3インデックスセレクタ index selector (第2.3.3節): 配列の
インデックス付き子を選択 (0始まり)
0💯5配列スライスセレクタ array slice selector (第2.3.4節):
配列の start:end:step
?<logical-expr>フィルタセレクタ filter selector (第2.3.5節): 論理
式を用いて特定の子を選択
length(@.foo)関数拡張 function extension (第2.4節): フィルタ式内で
関数を呼び出す

表1: JSONPath 構文の概観

1.5 JSONPath Examples (JSONPath の例)​

本節は参考情報です. JSONPath 式の例を示します.

例は図1に示す単純な JSON 値に基づきます. 書店 (自転車もある) を表します.

{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
}
}

図1: 例となる JSON 値

表2はこの例に適用しうる JSONPath クエリと意図された結果の一部を示します.

JSONPathIntended Result (意図された結果)
$.store.book[*].author店にあるすべての本の著者
$..authorすべての著者
$.store.*店にあるすべてのもの, すなわち
いくつかの本と赤い自転車
$.store..price店にあるすべてのものの価格
$..book[2]3冊目の本
$..book[2].author3冊目の本の著者
$..book[2].publisher空の結果: 3冊目の本に
"publisher" メンバがない
$..book[-1]順序上最後の本
$..book[0,1]最初の2冊
$..book[:2]
$..book[[email protected]]ISBN があるすべての本
$..book[[email protected]<10]10 未満のすべての本
$..*入力値に含まれるすべての
メンバ値と配列要素

表2: 例 JSON 値に適用した場合の JSONPath 式の例と意図された結果