功能¶
- JEP
3
- 作者
迈克尔·道林,詹姆斯·萨耶维尼
- 状态
认可的
- 创建
2013年11月27日
摘要¶
本文件建议修改 JMESPath grammar 支持函数表达式。
动机¶
函数允许用户轻松转换和过滤JMESPath表达式中的数据。由于JMESPath目前是实现的,函数在 multi-select-list
和 multi-select-hash
表达式来格式化表达式的输出,以包含可能不在原始JSON输入中的数据。与过滤表达式相结合,函数将是一个强大的机制来执行任何类型的特殊比较,例如 length()
, contains()
等。
数据类型¶
为了支持功能,需要一个类型系统。使用JSON类型:
数字(JSON中的整数和双精度浮点格式)
一串
布尔 (
true
或false
)数组(一个有序的值序列)
对象(键值对的无序集合)
无效的
语法更改¶
函数在中定义 function-expression
规则如下。函数表达式是 expression
在任何地方都是有效的 expression
是允许的。
语法需要添加以下语法:
function-expression = unquoted-string (
no-args /
one-or-more-args )
no-args = "(" ")"
one-or-more-args = "(" ( function-arg *( "," function-arg ) ) ")"
function-arg = expression / number / current-node
current-node = "@"
expression
将需要更新以添加 function-expression
生产:
expression = sub-expression / index-expression / or-expression / identifier / "*"
expression =/ multi-select-list / multi-select-hash
expression =/ literal / function-expression
一个函数可以接受任意数量的参数,每个参数都可以是一个表达式。每个函数必须定义一个签名,该签名指定其预期参数的数目和允许的类型。函数可以是可变的。
当前节点¶
这个 current-node
令牌可用于表示正在计算的当前节点。这个 current-node
令牌对于需要将当前节点作为参数求值的函数很有用。例如,下面的表达式创建一个数组,其中包含 foo
对象后跟的值 foo["bar"]
.
foo[].[count(@), bar]
JMESPath假定所有函数参数都在当前节点上操作,除非参数是 literal
或 number
令牌。因此,一个像 @.bar
相当于 bar
,因此当前节点只允许作为裸表达式。
当前节点状态¶
在表达式的开头,当前节点的值是由JMESPath表达式计算的数据。计算表达式时,当前节点表示的值必须更改以反映当前正在计算的节点。在投影中时,当前节点值必须更改为当前由投影计算的节点。
功能评价¶
函数按应用顺序求值。每个参数必须是一个表达式,每个参数表达式必须在计算函数之前求值。然后用求值的函数参数调用函数。结果 function-expression
函数调用返回的结果。如果 function-expression
为不存在的函数求值,则JMESPath实现必须向调用方指示 unknown-function
发生错误。引发此错误的方式和时间是特定于实现的,但实现应向调用方指示发生了此特定错误。
函数可以有一个特定的arity,也可以是变量,参数数量最少。如果 function-expression
如果arity不匹配或未提供变量函数的最小参数数,则实现必须向调用方指示 invalid-arity
发生错误。引发此错误的方式和时间取决于实现。
每个函数签名声明其输入参数的类型。如果不满足任何类型约束,则实现必须指示 invalid-type
发生错误。
为了适应类型约束,提供了将类型转换为其他类型的函数 (to_string
, to_number
)定义如下。除非用户专门使用这些类型转换函数之一,否则不会发生显式类型转换。
函数表达式也允许作为子表达式的子元素。这使得函数可以与投影一起使用,这样就可以将函数应用于投影中的每个元素。例如,给定的输入数据 ["1", "2", "3", "notanumber", true]
,可以使用以下表达式将所有元素转换(和筛选)为数字:
search([].to_number(@), ``["1", "2", "3", "notanumber", true]``) -> [1, 2, 3]
这提供了一个简单的机制,以便在需要时显式地转换类型。
内置功能¶
JMESPath有各种内置函数,这些函数可以对不同的数据类型进行操作,如下所述。下面的每个函数都有一个签名,用于定义预期的输入类型和返回的输出类型:
return_type function_name(type $argname)
return_type function_name2(type1|type2 $argname)
如果一个函数可以为一个输入值接受多个类型,则用 |
. 如果解析的参数与签名中指定的类型不匹配,则 invalid-type
发生错误。
这个 array
类型可以进一步指定对元素类型的要求,如果它们希望强制执行同构类型。子类型由 [type]
,例如,下面的函数签名要求其输入参数解析为数字数组:
return_type foo(array[number] $argname)
作为一种速记 any
用于指示参数可以是任何类型 (array|object|number|string|boolean|null
)
下面的第一个函数, abs
详细讨论了以上几点。为了简洁起见,后续函数定义将不包括这些详细信息,但同样的规则也适用。
注解
所有与字符串相关的函数都是基于Unicode代码点定义的;它们不考虑规范化。
防抱死制动系统¶
number abs(number $value)
Returns the absolute value of the provided argument. The signature indicates
that a number is returned, and that the input argument $value
must
resolve to a number, otherwise a invalid-type
error is triggered.
下面是一个成功的例子。鉴于::
{"foo": -1, "bar": "2"}
评价 abs(foo)
工程如下:
根据当前数据计算输入参数:
search(foo, {"foo": -11, "bar": 2"}) -> -1
验证已解析参数的类型。在这种情况下
-1
属于类型number
所以它通过了类型检查。使用已解析的参数调用函数::
abs(-1) -> 1
- 价值
1
函数表达式的解析值 abs(foo)
.
- 价值
以下是评估的相同步骤 abs(bar)
:
根据当前数据计算输入参数:
search(foo, {"foo": -1, "bar": 2"}) -> "2"
验证已解析参数的类型。在这种情况下
"2
属于类型string
所以直接表示invalid-type
发生错误。
作为最后一个例子,下面是评估 abs(to_number(bar))
:
根据当前数据计算输入参数:
search(to_number(bar), {"foo": -1, "bar": "2"})
为了计算上述表达式,我们需要计算
to_number(bar)
::search(bar, {"foo": -1, "bar": "2"}) -> "2" # Validate "2" passes the type check for to_number, which it does. to_number("2") -> 2
现在我们可以计算原始表达式:
search(to_number(bar), {"foo": -1, "bar": "2"}) -> 2
使用最终解析的值调用函数::
abs(2) -> 2
价值
2
函数表达式的解析值abs(to_number(bar))
.
表情 |
结果 |
---|---|
|
1 |
|
1 |
|
|
平均¶
number avg(array[number] $elements)
返回所提供数组中元素的平均值。
空数组将产生null的返回值。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
15 |
|
|
|
|
|
|
|
|
|
包含¶
boolean contains(array|string $subject, array|object|string|number|boolean $search)
返回 true
如果给定 $subject
包含提供的 $search
字符串。
如果 $subject
是一个数组,如果数组中的一个元素等于提供的 $search
价值。
如果提供 $subject
是字符串,如果字符串包含提供的 $search
争论。
鉴于 |
表情 |
结果 |
---|---|---|
n/a |
|
|
n/a |
|
|
n/a |
|
|
n/a |
|
|
n/a |
|
|
|
|
|
|
|
|
|
|
|
塞尔¶
number ceil(number $value)
如果需要,通过向上舍入返回下一个最大的整数值。
表情 |
结果 |
---|---|
|
2 |
|
2 |
|
1 |
|
|
地板¶
number floor(number $value)
如果需要,通过向下舍入返回下一个最小的整数值。
表情 |
结果 |
---|---|
|
1 |
|
1 |
|
1 |
参加¶
string join(string $glue, array[string] $stringsarray)
返回所提供的 $stringsarray
数组使用 $glue
参数作为每个参数之间的分隔符。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
“a,b” |
|
|
“ab” |
|
|
|
|
|
|
钥匙¶
array keys(object $obj)
返回包含所提供对象的键的数组。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
长度¶
number length(string|array|object $subject)
使用以下类型规则返回给定参数的长度:
字符串:返回字符串中代码点的数目
array:返回数组中的元素数
object:返回对象中键值对的数目
鉴于 |
表情 |
结果 |
---|---|---|
n/a |
|
3 |
“当前” |
|
7 |
“当前” |
|
|
|
|
3 |
|
|
0 |
|
|
0 |
|
|
2 |
最大值¶
number max(array[number] $collection)
返回在提供的数组参数中找到的最大值。
空数组将产生null的返回值。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
15 |
|
|
|
闽¶
number min(array[number] $collection)
返回在提供的 $collection
争论。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
10 |
|
|
|
分类¶
array sort(array $list)
此函数接受数组 $list
参数,并返回 $list
作为一个数组。
数组必须是字符串或数字的列表。字符串排序基于代码点。不考虑区域设置。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
to_string¶
string to_string(string|number|array|object|boolean $arg)
字符串-返回传入的值。
number/array/object/boolean—对象的JSON编码值。JSON编码器应该发出编码的JSON值,而不添加任何额外的新行。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
to_number¶
number to_number(string|number $arg)
字符串-返回解析后的数字。任何符合
json-number
支持生产。number-返回传入的值。
数组-空
对象-空
布尔值-空
符合性测试¶
A functions.json
将添加到符合性测试套件中。测试套件将添加以下新错误类型:
未知函数
无效arity
无效的类型
合规性没有规定 when 将引发错误,因为这将取决于实现细节。为了使实现兼容,它们需要指示在尝试计算JMESPath表达式时发生错误。
历史¶
这个JEP最初提出了字面语法。这个JEP的文字部分被删除并添加到jep7中。
这个JEP最初指定类型匹配应该返回null。它已被更新以指定应该发生无效类型错误。