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

2.4. Function Extensions (関数拡張)

2.4. Function Extensions (関数拡張)

先行する小節で定義したフィルタ式の機能に加え, JSONPath はフィルタ式の機能を追加するために用いうる拡張点を定義します: "Function Extensions (関数拡張)".

本節は拡張点と, この拡張点を用いる一部の関数拡張を定義します. これらの仕組みは拡張点を用いるよう設計されていますが, JSONPath 仕様の不可分の一部であり, 本仕様の他の不可分の部分と同様に実装されることが期待されます.

function extension (関数拡張) は登録名 (第3.2節参照) を定義し, ゼロ個以上の引数の列に適用して結果を生成します. 登録された各関数名は一意です.

関数拡張は, その評価が副作用なく行われるよう定義しなければなりません (MUST). すなわち, それを含む式について評価順や short-circuiting (短絡) と完全評価の選択のあらゆる組み合わせが同一結果に至らなければなりません. (注: メモ化やログはこの意味では副作用ではありません. 実装レベルでのみ可視であり, 評価結果に影響しません.)

function-name       = function-name-first *function-name-char
function-name-first = LCALPHA
function-name-char = function-name-first / "_" / DIGIT
LCALPHA = %x61-7A ; "a".."z"
function-expr       = function-name "(" S [function-argument
*(S "," S function-argument)] S ")"
function-argument = literal /
filter-query / ; (includes singular-query)
logical-expr /
function-expr

クエリ内の関数式はすべて上記 ABNF に適合して整形式であり, かつ well-typed でなければなりません. そうでなければ JSONPath 実装はエラーを発生させなければなりません (MUST) (第2.1節参照). どの関数式が well-typed かを定義する前に, 型システムを導入します.

2.4.1 Type System for Function Expressions (関数式の型システム)

各パラメータと関数拡張の結果は宣言型を持たなければなりません.

宣言型により, JSONPath クエリが適用されるクエリ引数とは独立に, JSONPath クエリの well-typedness (型の整い) を検査できます.

表13は, 含みうるインスタンスの観点から利用可能な型を定義します.

Type (型)Instances (インスタンス)
ValueTypeJSON 値または Nothing
LogicalTypeLogicalTrue または LogicalFalse
NodesTypeNodelists

表13: 関数拡張の型システム

注:

  • JSONPath 構文で直接表現できるインスタンスは, ValueType 内の特定の JSON 値 (JSONPath ではプリミティブ値に限定) をリテラルとして表したものに限られます.

  • 特別な結果 Nothing は JSON 値の欠如を表し, null を含むいかなる JSON 値とも異なります.

  • LogicalTrue と LogicalFalse は, リテラル true と false が表す JSON 値とは無関係です.

2.4.2 Type Conversion (型変換)

論理式においてクエリを少なくとも1つのノードの存在をテストすることで用いるのと同様に, 宣言型 NodesType の関数式は宣言型 LogicalType のパラメータへの関数引数として次の等価変換規則で用いられます:

  • ノードリストが1つ以上のノードを含むなら, 変換結果は LogicalTrue です.

  • ノードリストが空なら, 変換結果は LogicalFalse です.

注:

  • ノードリストから値を取り出す方法は複数あるため, NodesType から ValueType への暗黙変換は驚きを招きうるため定義していません.

  • 宣言型 NodesType の関数式は, NodesType のパラメータを取り ValueType を返す value() などの関数拡張の呼び出しで包むことで, 間接的に宣言型 ValueType のパラメータに渡せます (第2.4.8節参照).

この型システムの観点から関数式の well-typedness を定義できます.

2.4.3 Well-Typedness of Function Expressions (関数式の型の整い)

関数式が well-typed であるには:

  1. その宣言型が出現する文脈で well-typed でなければなりません.

文法上, 関数式は次の3つの直接文脈に現れ, well-typedness に関して次の条件が従います:

論理式の test-expr として: 関数の宣言結果型は LogicalType であるか, (第2.4.2節に従う変換を生じさせ) NodesType です.

比較の comparable として: 関数の宣言結果型は ValueType です.

別の関数式の function-argument として: 関数の宣言結果型は外側の関数の対応するパラメータに対して次の規則を満たします.

  1. 引数は対応するパラメータの宣言型に対して well-typed でなければなりません.

関数式の引数は, 次のいずれかに従うとき各引数が対応するパラメータの宣言型に用いうるとき well-typed です:

  • 引数がパラメータの宣言型と同じ宣言結果型を持つ関数式であるとき.

  • パラメータの宣言型が LogicalType であり, 引数が次のいずれかであるとき:

    • 宣言結果型 NodesType の関数式. この場合, 引数は第2.4.2節に従い LogicalType に変換されます.

    • 関数式でない logical-expr.

  • パラメータの宣言型が NodesType であり, 引数がクエリ (singular query を含む) であるとき.

  • パラメータの宣言型が ValueType であり, 引数が次のいずれかであるとき:

    • リテラルとして表された値.

    • singular query. この場合:

      o クエリが単一ノードからなるノードリストを生成すれば, 引数はそのノードの値です.

      o クエリが空のノードリストを生成すれば, 引数は特別な結果 Nothing です.

2.4.4 length() Function Extension (length() 関数拡張)

Parameters: 1. ValueType

Result: ValueType (符号なし整数または Nothing)

length() 関数拡張は, 値の長さを計算しフィルタ式内のさらなる処理に利用する方法を提供します:

$[?length(@.authors) >= 5]

唯一の引数は ValueType のインスタンスです (上の例のように singular query から取られうります). 結果も ValueType のインスタンスです: 符号なし整数または特別な結果 Nothing.

  • 引数値が文字列なら, 結果は文字列内の Unicode スカラー値の数です.

  • 引数値が配列なら, 結果は配列の要素数です.

  • 引数値がオブジェクトなら, 結果はオブジェクトのメンバ数です.

  • その他の引数値に対しては, 結果は特別な結果 Nothing です.

2.4.5 count() Function Extension (count() 関数拡張)

Parameters: 1. NodesType

Result: ValueType (符号なし整数)

count() 関数拡張は, ノードリスト内のノード数を得てフィルタ式内のさらなる処理に利用する方法を提供します:

$[?count(@.*.author) >= 5]

唯一の引数はノードリストです. 結果はノードリスト内のノード数を与える値 (符号なし整数) です.

注:

  • ノードリストの重複除去は行いません.

  • ノードリストのノード数は, 値や子の有無に関わらず数えます. 例えば空でない singular nodelist に対する count(@) は常に1です.

2.4.6 match() Function Extension (match() 関数拡張)

Parameters: 1. ValueType (string)

  1. ValueType ([RFC9485] に適合する string)

Result: LogicalType

match() 関数拡張は, (第2.4.7節参照, 文字列全体が) 与えられた正規表現に一致するかどうかを検査する方法を提供します. 正規表現の形式は [RFC9485] に記載されます.

$[?match(@.date, "1974-05-..")]

引数は ValueType のインスタンスです (上の例の最初の引数のように singular query から取られうります). 第1引数が文字列でないか, 第2引数が [RFC9485] に適合する文字列でない場合, 結果は LogicalFalse です. そうでなければ, 第1引数の文字列を第2引数の文字列に含まれる I-Regexp に照合します. 文字列が I-Regexp に一致すれば結果は LogicalTrue, そうでなければ LogicalFalse です.

2.4.7 search() Function Extension (search() 関数拡張)

Parameters: 1. ValueType (string)

  1. ValueType ([RFC9485] に適合する string)

Result: LogicalType

search() 関数拡張は, 与えられた文字列が与えられた正規表現に一致する部分文字列を含むかどうかを検査する方法を提供します. 正規表現の形式は [RFC9485] に記載されます.

$[?search(@.author, "[BR]ob")]

引数は ValueType のインスタンスです (上の例の最初の引数のように singular query から取られうります). 第1引数が文字列でないか, 第2引数が [RFC9485] に適合する文字列でない場合, 結果は LogicalFalse です. そうでなければ, 第1引数の文字列から第2引数の文字列に含まれる I-Regexp に一致する部分文字列を探索します. そのような部分文字列が少なくとも1つ存在すれば結果は LogicalTrue, そうでなければ LogicalFalse です.

2.4.8 value() Function Extension (value() 関数拡張)

Parameters: 1. NodesType

Result: ValueType

value() 関数拡張は, NodesType のインスタンスを値に変換しフィルタ式内のさらなる処理に利用する方法を提供します:

$[?value(@..color) == "red"]

唯一の引数は NodesType のインスタンスです (上の例のように filter-query から取られうります). 結果は ValueType のインスタンスです.

  • 引数が単一ノードを含むなら, 結果はそのノードの値です.

  • 引数が空のノードリストか複数ノードを含むなら, 結果は Nothing です.

注: singular query は ValueType が期待される任意の場所で用いられうるため, singular query に value() を使う必要はありません.

2.4.9 Examples (例)

QueryComment
$[?length(@) < 3]well-typed
$[?length(@.*) < 3]@.* は non-singular query のため not well-typed
$[?count(@.*) == 1]well-typed
$[?count(1) == 1]1 はクエリでも関数式でもないため not well-typed
$[?count(foo(@.*))foo() が NodesType パラメータと
== 1]NodesType 結果型の関数拡張なら well-typed
$[?match(@.timezone,well-typed
'Europe/.*')]
$[?match(@.timezone,LogicalType は比較に使えないため
'Europe/.*') ==not well-typed
true]
$[?value(@..color)well-typed
== "red"]
$[?value(@..color)]ValueType は test expression に使えないため
not well-typed
$[?bar(@.a)]任意の宣言型のパラメータと LogicalType 結果型の
関数 bar() なら well-typed
$[?bnl(@.*)]NodesType または LogicalType パラメータと
LogicalType 結果型の関数 bnl() なら well-typed
$[?blt(1==1)]LogicalType パラメータと LogicalType 結果型の
関数 blt() なら well-typed
$[?blt(1)]同じ blt() に対し 1 はクエリ, logical-expr,
関数式でないため not well-typed
$[?bal(1)]ValueType パラメータと LogicalType 結果型の
関数 bal() なら well-typed

表14: 関数式の例