跳到主要内容

2.4. Function Extensions (函数扩展)

2.4. Function Extensions (函数扩展)

除前述小节定义的 filter expression 功能外, JSONPath 定义了可用于增加 filter expression 功能的扩展点: "Function Extensions (函数扩展)".

本节定义该扩展点及若干使用该扩展点的 function extensions. 虽然这些机制设计为使用该扩展点, 它们是 JSONPath 规范的组成部分, 应像本规范任何其他组成部分一样实现.

Function extension 定义一个 registered name (见第 3.2 节), 可应用于零个或多个实参序列, 产生结果. 每个已注册函数名唯一.

Function extension 必须定义为求值无副作用, 即包含它的表达式所有可能的求值顺序以及短路或非短路选择必须导致相同结果. (注意: Memoization (记忆化) 或 logging (日志) 在此意义下不算副作用, 因为它们仅在实现层可见, 不影响求值结果.)

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

查询中的 function expressions 必须 well-formed (符合上述 ABNF) 且 well-typed; 否则 JSONPath 实现必须报错 (见第 2.1 节). 为定义哪些 function expressions well-typed, 先引入类型系统.

2.4.1. Type System for Function Expressions (函数表达式的类型系统)

每个 parameter 与 function extension 的结果必须具有 declared type.

Declared types 使得可在不依赖 JSONPath 查询所作用的任何 query argument 的情况下检查 JSONPath 查询的 well-typedness.

表 13 按所含实例定义可用类型.

TypeInstances
ValueTypeJSON values 或 Nothing
LogicalTypeLogicalTrue 或 LogicalFalse
NodesTypeNodelists

表 13: Function Extension 类型系统

说明:

  • 仅部分 ValueType 的 JSON 值可作为 literal 直接在 JSONPath 语法中表示 (在 JSONPath 中限于 primitive values).

  • 特殊结果 Nothing 表示不存在 JSON 值, 与包括 null 在内的任何 JSON 值不同.

  • LogicalTrue 与 LogicalFalse 与字面量 true 与 false 表示的 JSON 值无关.

2.4.2. Type Conversion (类型转换)

正如可通过检测是否至少存在一个节点在 logical expression 中使用查询 (第 2.3.5.2.1 节), declared type 为 NodesType 的 function expression 可作为 declared type 为 LogicalType 的 parameter 的函数实参, 等价转换规则为:

  • 若 nodelist 包含一个或多个节点, 转换结果为 LogicalTrue.

  • 若 nodelist 为空, 转换结果为 LogicalFalse.

说明:

  • 从 nodelist 提取值可有多种方式, 因此隐式从 NodesType 到 ValueType 的转换可能令人意外, 故未定义.

  • Declared type 为 NodesType 的 function expression 可通过包裹在对 NodesType 取参并返回 ValueType 的 function extension (例如 value(), 见第 2.4.8 节) 的调用中间接用作 ValueType parameter 的实参.

现可在该类型系统下定义 function expressions 的 well-typedness.

2.4.3. Well-Typedness of Function Expressions (函数表达式的类型良好性)

Function expression 要 well-typed:

  1. 其 declared type 在出现的上下文中必须 well-typed.

按文法, function expression 可出现在三种直接上下文中, 导致以下 well-typedness 条件:

作为 logical expression 中的 test-expr: 函数的声明结果类型为 LogicalType 或 (按第 2.4.2 节转换) NodesType.

作为 comparison 中的 comparable: 函数的声明结果类型为 ValueType.

作为另一 function expression 中的 function-argument: 函数的声明结果类型满足封闭函数对应 parameter 的下列规则.

  1. 其实参对于对应 parameter 的声明类型必须 well-typed.

Function expression 的实参在以下任一条件成立时对对应 parameter 的声明类型 well-typed:

  • 实参为具有与 parameter 声明类型相同声明结果类型的 function expression.

  • Parameter 声明类型为 LogicalType 且实参为以下之一:

  • Declared result type 为 NodesType 的 function expression. 此时实参按第 2.4.2 节转换为 LogicalType.

  • 非 function expression 的 logical-expr.

  • Parameter 声明类型为 NodesType 且实参为 query (含 singular query).

  • Parameter 声明类型为 ValueType 且实参为以下之一:

  • 以 literal 表示的值.

  • Singular query. 此时:

o 若查询产生由单个节点组成的 nodelist, 实参为该节点的值.

o 若查询产生 empty nodelist, 实参为特殊结果 Nothing.

2.4.4. length() Function Extension

Parameters: 1. ValueType

Result: ValueType (unsigned integer 或 Nothing)

length() function extension 提供计算值长度并在 filter expression 中进一步使用的方式:

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

其唯一实参为 ValueType 实例 (可来自 singular query, 如上例). 结果亦为 ValueType 实例: 无符号整数或特殊结果 Nothing.

  • 若实参值为 string, 结果为 string 中 Unicode scalar values 的数量.

  • 若实参值为 array, 结果为元素数量.

  • 若实参值为 object, 结果为 member 数量.

  • 对任何其他实参值, 结果为特殊结果 Nothing.

2.4.5. count() Function Extension

Parameters: 1. NodesType

Result: ValueType (unsigned integer)

count() function extension 提供获取 nodelist 中节点数并在 filter expression 中进一步使用的方式:

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

其唯一实参为 nodelist. 结果为给出 nodelist 中节点数的值 (无符号整数).

说明:

  • 不对 nodelist 去重.

  • 节点数与节点值或其子节点无关, 例如非空 singular nodelist 的 count(@) 恒为 1.

2.4.6. match() Function Extension

Parameters: 1. ValueType (string)

  1. ValueType (string conforming to [RFC9485])

Result: LogicalType

match() function extension 提供检测给定 string 是否 (整体地; 见第 2.4.7 节) 匹配给定 regular expression 的方式, 正则形式见 [RFC9485].

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

其实参为 ValueType 实例 (可来自 singular query, 如上例第一实参). 若第一实参不是 string 或第二实参不是符合 [RFC9485] 的 string, 结果为 LogicalFalse. 否则将第一实参的 string 与第二实参 string 中所含的 I-Regexp 匹配; 匹配则为 LogicalTrue, 否则 LogicalFalse.

2.4.7. search() Function Extension

Parameters: 1. ValueType (string)

  1. ValueType (string conforming to [RFC9485])

Result: LogicalType

search() function extension 提供检测给定 string 是否包含匹配给定 regular expression 的子串的方式, 正则形式见 [RFC9485].

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

其实参为 ValueType 实例 (可来自 singular query, 如上例第一实参). 若第一实参不是 string 或第二实参不是符合 [RFC9485] 的 string, 结果为 LogicalFalse. 否则在第一实参 string 中搜索匹配第二实参 string 中所含 I-Regexp 的子串; 若至少存在一个此类子串则为 LogicalTrue, 否则 LogicalFalse.

2.4.8. value() Function Extension

Parameters: 1. NodesType

Result: ValueType

value() function extension 提供将 NodesType 实例转换为值并在 filter expression 中进一步使用的方式:

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

其唯一实参为 NodesType 实例 (可来自 filter-query, 如上例). 结果为 ValueType 实例.

  • 若实参包含单个节点, 结果为该节点的值.

  • 若实参为 empty nodelist 或包含多个节点, 结果为 Nothing.

注意: Singular query 可在任何期望 ValueType 处使用, 因此无需对 singular query 使用 value() function extension.

2.4.9. Examples (示例)

QueryComment
$[?length(@) < 3]well-typed
$[?length(@.*) < 3]非 well-typed, 因为 @.* 为
非 singular query
$[?count(@.*) == 1]well-typed
$[?count(1) == 1]非 well-typed, 因为 1 不是
query 或 function expression
$[?count(foo(@.*))well-typed, 其中 foo() 为
== 1]NodesType 形参且结果为
NodesType 的 function extension
$[?match(@.timezone,well-typed
'Europe/.*')]
$[?match(@.timezone,非 well-typed, 因 LogicalType
'Europe/.*') ==不可用于比较
true]
$[?value(@..color)well-typed
== "red"]
$[?value(@..color)]非 well-typed, 因 ValueType
不可用于 test expression
$[?bar(@.a)]对任意 bar() 均 well-typed,
若其形参为任意声明类型且
结果为 LogicalType
$[?bnl(@.*)]对任意 bnl() 均 well-typed,
若其形参为 NodesType 或
LogicalType 且结果为 LogicalType
$[?blt(1==1)]well-typed, 其中 blt() 的
形参为 LogicalType 且结果为
LogicalType
$[?blt(1)]对同一 blt() 非 well-typed,
因为 1 不是 query, logical-expr,
或 function expression
$[?bal(1)]well-typed, 其中 bal() 的
形参为 ValueType 且结果为
LogicalType

表 14: Function Expression 示例