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

2.1. Overview (概観)

2.1. Overview (概観)

JSONPath expression (式) は文字列であり, JSON 値 (query argument (クエリ引数)) に適用されると, 引数のゼロ個以上のノードを選択し, これらのノードをノードリストとして出力します.

クエリは UTF-8 でエンコードしなければなりません (MUST). 本ドキュメントで与えるクエリの文法は, その UTF-8 形式をまず [RFC3629] に記載されるとおり Unicode スカラー値に復号することを前提とします. 等価な結果に至る実装アプローチも可能です.

JSONPath クエリとして用いる文字列は well-formed (整形式) かつ valid (妥当) である必要があります. 本ドキュメントの ABNF 構文に適合するならば文字列は整形式の JSONPath クエリです. 整形式の JSONPath クエリは, さらに本ドキュメントが課す次の2つの意味論的要件も満たす場合に妥当です:

  1. JSONPath 処理に関係する JSONPath クエリ内の整数 (例: インデックス値と step) は, Internet JSON (I-JSON) で定義される正確な整数値の範囲内になければなりません (MUST) ([RFC7493] 第2.2節参照), すなわち区間 [-(2^53)+1, (2^53)-1] 内です.

  2. function extensions (関数拡張) の使用は第2.4.3節に記載されるとおり well-typed (型が整っている) でなければなりません (MUST).

JSONPath 実装は, 整形式かつ妥当でないクエリに対してはエラーを発生させなければなりません (MUST). JSONPath クエリの整形式性と妥当性は, クエリが適用される JSON 値とは独立です. クエリを値に適用する際に, クエリの整形式性・妥当性に関するさらなるエラーを発生させてはなりません. これによりクエリの整形式性・妥当性のエラーと, データの欠陥に実際起因しうる不一致とが明確に分離されます.

妥当なクエリが期待する構造とデータに見つかる構造との不一致は空のクエリ結果につながりうるため, いずれかのバグを示しうます. JSONPath 実装はしたがって, 空の結果の原因究明に役立つ診断情報をアプリケーション開発者に提供することが望ましいでしょう.

明らかに, 実装は JSONPath クエリ実行中にリソース枯渇などで失敗しうりますが, 本ドキュメントではモデル化しません. ただし実装は黙って誤動作してはなりません (MUST NOT). 特に, 妥当な JSONPath クエリが, クエリを正しく処理するには大きすぎる構造化値 (例: 正確な値の範囲外の数値処理を要する) に対して評価される場合, 実装はオーバーフローを示す必要があります (MUST).

(HTTP のエラーモデルに馴染みのある読者は, 整形式性と妥当性を考える際に 400 系エラー, リソース枯渇など関連エラーを 500 系に相当するものとして認識しうます.)

2.1.1 Syntax (構文)

構文的に JSONPath クエリは root identifier ($) からなり, それはクエリ引数のルートノードを含むノードリストを表し, 続けてゼロ個以上の segments (セグメント) の列が続きます.

jsonpath-query      = root-identifier segments
segments = *(S segment)
B                   = %x20 /    ; Space
%x09 / ; Horizontal tab
%x0A / ; Line feed or New line
%x0D ; Carriage return
S = *B ; optional blank space

セグメントの構文と意味論は第2.5節で定義します.

2.1.2 Semantics (意味論)

本ドキュメントにおける JSONPath クエリの意味論は, 要求される結果を定義し, 実装の内部動作を規定しません. 本ドキュメントは手続き的な段階的説明で意味論を述べることがありますが, そのような説明は, 任意の実装が同一の結果を生成しなければならない (MUST) という意味でのみ規範的であり, 実装者が同一アルゴリズムを用いることを要求するものではありません.

意味論とは, 妥当なクエリが値 (query argument) に対して実行されノードリスト (値のゼロ個以上のノードのリスト) を生成するということです.

クエリはルート識別子とゼロ個以上のセグメントの列であり, 各セグメントは直前のルート識別子またはセグメントの結果に適用され, 次のセグメントへの入力を提供します. これらの結果と入力はノードリストの形を取ります.

ルート識別子から得られるノードリストは単一ノード (クエリ引数) を含みます. 最後のセグメントから得られるノードリストがクエリの結果として提示されます. 具体的な API によっては, ノードにおける JSON 値の配列, ノードを参照する Normalized Path の配列, 両方, または実装が望む別表現として提示される場合があります. 注: 空のノードリストも妥当なクエリ結果です.

セグメントは入力ノードリストの各ノードに順に作用し, 得られたノードリストは, それらが派生した入力ノードリストの順に連結され, セグメントの結果となります. ノードは複数回選択されうり, その回数だけノードリストに現れます. 重複ノードは除去されません.

構文的に妥当なセグメントはクエリ実行時にエラーを生成してはなりません (MUST NOT). これは, 配列の範囲外のインデックスを用いるなど, 誤りとみなしうる操作が, 単により少ないノードが選択される結果にすぎないことを意味します. (この性質に関する追加の議論は第2.1節の導入にあります.)

このアプローチの帰結として, いずれかのセグメントが空のノードリストを生成すれば, クエリ全体は空のノードリストを生成します.

クエリの意味論が実装に複数の順序付けの選択肢を与える場合, 特定の実装はクエリの連続実行で異なる順序付けを生成してもよいです (MAY).

2.1.3 Example (例)

次の例を考えます. クエリ引数が {"a":[{"b":0},{"b":1},{"c":2}]} のとき, クエリ $.a[*].b は次のノードのリスト (ここでは値で示す) を選択します: 0, 1.

クエリは $ に続く3つのセグメント .a, [*], .b からなります.

まず $ はクエリ引数のみからなるノードリストを生成します.

次に .a は任意のオブジェクト入力ノードから, 入力ノードのメンバ名 "a" に対応するメンバ値のノードを選択します. 結果は再び単一ノードを含むリストです: [{"b":0},{"b":1},{"c":2}].

次に [*] は入力配列ノードからすべての要素を選択します. 結果は3つのノードのリストです: {"b":0}, {"b":1}, {"c":2}.

最後に .b はメンバ名 b を持つ任意のオブジェクト入力ノードから, その名前に対応するメンバ値のノードを選択します. 結果は 0, 1 を含むリストです. これは長さ1のリスト2つ (それぞれ 0, 1) と長さゼロのリスト1つの連結です.