JMESPath规范¶
本文档描述jmespath的规范。
如果您想了解JMESPath语言,请参阅 JMESPath教程 以及 JMESPath示例 页。
在规范中,通过使用 search
功能。此函数的语法为:
search(<jmespath expr>, <JSON document>) -> <return value>
为了简单起见,jmespath表达式和JSON文档不被引用。例如::
search(foo, {"foo": "bar"}) -> "bar"
对JSON文档应用JMESPath表达式的结果将 总是 得到有效的JSON,前提是在评估过程中没有错误。结构化数据输入,结构化数据输出。
这也意味着,除了JMESPath表达式类型之外,JMESPath只支持JSON支持的相同类型:
数字(JSON中的整数和双精度浮点格式)
一串
布尔 (
true
或false
)数组(一个有序的值序列)
对象(键值对的无序集合)
无效的
表达式类型在 函数表达式 部分。
实现可以将相应的JSON类型映射到它们的等效语言。例如,JSON null
可以映射到 None
在python中,以及 nil
用ruby和go。
语法¶
语法是使用ABNF指定的,如中所述 RFC4234
expression = sub-expression / index-expression / comparator-expression
expression =/ or-expression / identifier
expression =/ and-expression / not-expression / paren-expression
expression =/ "*" / multi-select-list / multi-select-hash / literal
expression =/ function-expression / pipe-expression / raw-string
expression =/ current-node
sub-expression = expression "." ( identifier /
multi-select-list /
multi-select-hash /
function-expression /
"*" )
pipe-expression = expression "|" expression
or-expression = expression "||" expression
and-expression = expression "&&" expression
not-expression = "!" expression
paren-expression = "(" expression ")"
index-expression = expression bracket-specifier / bracket-specifier
multi-select-list = "[" ( expression *( "," expression ) ) "]"
multi-select-hash = "{" ( keyval-expr *( "," keyval-expr ) ) "}"
keyval-expr = identifier ":" expression
bracket-specifier = "[" (number / "*" / slice-expression) "]" / "[]"
bracket-specifier =/ "[?" expression "]"
comparator-expression = expression comparator expression
slice-expression = [number] ":" [number] [ ":" [number] ]
comparator = "<" / "<=" / "==" / ">=" / ">" / "!="
function-expression = unquoted-string (
no-args /
one-or-more-args )
no-args = "(" ")"
one-or-more-args = "(" ( function-arg *( "," function-arg ) ) ")"
function-arg = expression / expression-type
current-node = "@"
expression-type = "&" expression
raw-string = "'" *raw-string-char "'"
raw-string-char = (%x20-26 / %x28-5B / %x5D-10FFFF) / preserved-escape /
raw-string-escape
preserved-escape = escape (%x20-26 / %28-5B / %x5D-10FFFF)
raw-string-escape = escape ("'" / escape)
literal = "`" json-value "`"
unescaped-literal = %x20-21 / ; space !
%x23-5B / ; # - [
%x5D-5F / ; ] ^ _
%x61-7A ; a-z
%x7C-10FFFF ; |}~ ...
escaped-literal = escaped-char / (escape %x60)
number = ["-"]1*digit
digit = %x30-39
identifier = unquoted-string / quoted-string
unquoted-string = (%x41-5A / %x61-7A / %x5F) *( ; A-Za-z_
%x30-39 / ; 0-9
%x41-5A / ; A-Z
%x5F / ; _
%x61-7A) ; a-z
quoted-string = quote 1*(unescaped-char / escaped-char) quote
unescaped-char = %x20-21 / %x23-5B / %x5D-10FFFF
escape = %x5C ; Back slash: \
quote = %x22 ; Double quote: '"'
escaped-char = escape (
%x22 / ; " quotation mark U+0022
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX
; The ``json-value`` is any valid JSON value with the one exception that the
; ``%x60`` character must be escaped. While it's encouraged that implementations
; use any existing JSON parser for this grammar rule (after handling the escaped
; literal characters), the grammar rule is shown below for completeness::
json-value = false / null / true / json-object / json-array /
json-number / json-quoted-string
false = %x66.61.6c.73.65 ; false
null = %x6e.75.6c.6c ; null
true = %x74.72.75.65 ; true
json-quoted-string = %x22 1*(unescaped-literal / escaped-literal) %x22
begin-array = ws %x5B ws ; [ left square bracket
begin-object = ws %x7B ws ; { left curly bracket
end-array = ws %x5D ws ; ] right square bracket
end-object = ws %x7D ws ; } right curly bracket
name-separator = ws %x3A ws ; : colon
value-separator = ws %x2C ws ; , comma
ws = *(%x20 / ; Space
%x09 / ; Horizontal tab
%x0A / ; Line feed or New line
%x0D ; Carriage return
)
json-object = begin-object [ member *( value-separator member ) ] end-object
member = quoted-string name-separator json-value
json-array = begin-array [ json-value *( value-separator json-value ) ] end-array
json-number = [ minus ] int [ frac ] [ exp ]
decimal-point = %x2E ; .
digit1-9 = %x31-39 ; 1-9
e = %x65 / %x45 ; e E
exp = e [ minus / plus ] 1*DIGIT
frac = decimal-point 1*DIGIT
int = zero / ( digit1-9 *DIGIT )
minus = %x2D ; -
plus = %x2B ; +
zero = %x30 ; 0
除了语法之外,还有以下从最弱到最紧绑定的标记优先级:
管道:
|
或:
||
还有:
&&
一元不:
!
R球拍:
]
标识符¶
identifier = unquoted-string / quoted-string
unquoted-string = (%x41-5A / %x61-7A / %x5F) *( ; A-Za-z_
%x30-39 / ; 0-9
%x41-5A / ; A-Z
%x5F / ; _
%x61-7A) ; a-z
quoted-string = quote 1*(unescaped-char / escaped-char) quote
unescaped-char = %x20-21 / %x23-5B / %x5D-10FFFF
escape = %x5C ; Back slash: \
quote = %x22 ; Double quote: '"'
escaped-char = escape (
%x22 / ; " quotation mark U+0022
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX
安 identifier
是最基本的表达式,可用于从JSON文档中提取单个元素。的返回值 identifier
与标识符关联的值。如果 identifier
在JSON文档中不存在,而不是 null
返回值。
根据上面列出的语法规则,标识符可以是一个或多个字符,并且必须以 A-Za-z_
.
也可以引用标识符。当标识符中没有指定字符时,这是必需的 unquoted-string
语法规则。在这种情况下,标识符用双引号指定,后跟任意数量的 unescaped-char
或 escaped-char
字符,后跟双引号。这个 quoted-string
rule与JSON字符串的语法规则相同,因此任何有效的字符串都可以在双引号、包括JSON支持的转义序列和六个字符的unicode转义序列之间使用。
Note that any identifier that does not start with A-Za-z_
must
be quoted.
实例¶
search(foo, {"foo": "value"}) -> "value"
search(bar, {"foo": "value"}) -> null
search(foo, {"foo": [0, 1, 2]}) -> [0, 1, 2]
search("with space", {"with space": "value"}) -> "value"
search("special chars: !@#", {"special chars: !@#": "value"}) -> "value"
search("quote\"char", {"quote\"char": "value"}) -> "value"
search("\u2713", {"\u2713": "value"}) -> "value"
SubExpressions¶
sub-expression = expression "." ( identifier /
multi-select-list /
multi-select-hash /
function-expression /
"*" )
子表达式是用“.”字符分隔的两个表达式的组合。子表达式的评估如下:
使用原始JSON文档计算左侧的表达式。
使用左侧表达式求值的结果计算右侧表达式。
在伪代码中:
left-evaluation = search(left-expression, original-json-document)
result = search(right-expression, left-evaluation)
子表达式本身就是表达式,因此可以有多个级别的子表达式: grandparent.parent.child
.
实例¶
给定一个JSON文档: {{"foo": {{"bar": "baz"}}}}
,以及jmespath表达式: foo.bar
,评估过程为:
left-evaluation = search("foo", {"foo": {"bar": "baz"}}) -> {"bar": "baz"}
result = search("bar": {"bar": "baz"}) -> "baz"
这个例子的最终结果是 "baz"
.
其他示例:
search(foo.bar, {"foo": {"bar": "value"}}) -> "value"
search(foo."bar", {"foo": {"bar": "value"}}) -> "value"
search(foo.bar, {"foo": {"baz": "value"}}) -> null
search(foo.bar.baz, {"foo": {"bar": {"baz": "value"}}}) -> "value"
索引表达式¶
index-expression = expression bracket-specifier / bracket-specifier
bracket-specifier = "[" (number / "*") "]" / "[]"
索引表达式用于访问列表中的元素。索引是基于0的,索引0是指列表的第一个元素。负数是有效的索引。负数表示索引相对于列表的结尾,特别是:
negative-index == (length of array) + negative-index
给定一个数组的长度 N
,一个索引 -1
等于正指数 N - 1
,它是列表的最后一个元素。如果索引表达式引用的索引大于数组的长度,则 null
返回。
语法规则 expression bracket-specifier
这个 expression
首先计算,然后从 expression
作为输入提供给 bracket-specifier
.
在中使用“*”字符 bracket-specifier
在下面的 wildcard expressions
部分。
片¶
slice-expression = [number] ":" [number] [ ":" [number] ]
切片表达式允许您选择数组的连续子集。一片有一片 start
, stop
和 step
价值观。切片的一般形式是 [start:stop:step]
,但每个组件都是可选的,可以省略。
注解
JMESPath中的切片与python切片具有相同的语义。如果您熟悉python切片,那么就熟悉JMESPath切片。
给出了一个 start
, stop
和 step
值,则数组中的子元素按如下方式提取:
提取数组中的第一个元素是用
start
.提取数组中的最后一个元素是用
end - 1
.这个
step
值确定从数组中选择每个元素后要跳过的索引数。数组1(默认步骤)不会跳过任何索引。从数组中提取元素时,步长值为2将每隔一个索引跳过一次。步长值-1将从数组中以相反的顺序提取值。
切片表达式遵循以下规则:
如果给定的起始位置为负,则计算为数组的总长度加上给定的起始位置。
如果没有给定起始位置,如果给定步长大于0,则假定为0;如果给定步长小于0,则假定为数组的结束。
如果给定负停止位置,则将其计算为数组的总长度加上给定的停止位置。
如果没有给定停止位置,如果给定步长大于0,则假定为数组的长度;如果给定步长小于0,则假定为0。
如果省略给定步骤,则假定为1。
如果给定步骤为0,则必须引发错误。
如果被切片的元素不是数组,则结果是
null
.如果被切片的元素是一个数组并且没有产生结果,那么结果必须是空数组。
实例¶
search([0:4:1], [0, 1, 2, 3]) -> [0, 1, 2, 3]
search([0:4], [0, 1, 2, 3]) -> [0, 1, 2, 3]
search([0:3], [0, 1, 2, 3]) -> [0, 1, 2]
search([:2], [0, 1, 2, 3]) -> [0, 1]
search([::2], [0, 1, 2, 3]) -> [0, 2]
search([::-1], [0, 1, 2, 3]) -> [3, 2, 1, 0]
search([-2:], [0, 1, 2, 3]) -> [2, 3]
展平运算符¶
当字符序列 []
作为括号说明符提供,则对当前结果执行展平操作。展平运算符将当前结果中的子列表合并到单个列表中。“展平”操作符具有以下语义:
创建空结果列表。
迭代当前结果的元素。
如果当前元素不是列表,请添加到结果列表的末尾。
如果当前元素是列表,则将当前元素的每个元素添加到结果列表的末尾。
结果列表现在是新的当前结果。
一旦执行了展平操作,后续操作将被投影到展平列表上,其语义与通配符表达式相同。因此 [*]
和 []
那是 []
将首先展平当前结果中的子列表。
实例¶
search([0], ["first", "second", "third"]) -> "first"
search([-1], ["first", "second", "third"]) -> "third"
search([100], ["first", "second", "third"]) -> null
search(foo[0], {"foo": ["first", "second", "third"]) -> "first"
search(foo[100], {"foo": ["first", "second", "third"]) -> null
search(foo[0][0], {"foo": [[0, 1], [1, 2]]}) -> 0
或表达式¶
or-expression = expression "||" expression
or表达式将计算为左表达式或右表达式。如果左表达式的求值不是false,则将其用作返回值。如果正确表达式的求值不是false,则将其用作返回值。如果left或right表达式都不是非null,则返回null值。假值对应于以下任何条件:
空列表:
[]
空对象:
{{}}
空字符串:
""
假布尔值:
false
空值:
null
真值对应于任何非false的值。
实例¶
search(foo || bar, {"foo": "foo-value"}) -> "foo-value"
search(foo || bar, {"bar": "bar-value"}) -> "bar-value"
search(foo || bar, {"foo": "foo-value", "bar": "bar-value"}) -> "foo-value"
search(foo || bar, {"baz": "baz-value"}) -> null
search(foo || bar || baz, {"baz": "baz-value"}) -> "baz-value"
search(override || mylist[-1], {"mylist": ["one", "two"]}) -> "two"
search(override || mylist[-1], {"mylist": ["one", "two"], "override": "yes"}) -> "yes"
和表达式¶
and-expression = expression "&&" expression
and表达式将计算为左表达式或右表达式。如果左侧的表达式是一个类似于真值的值,则返回右侧的值。否则,将返回左侧表达式的结果。这也简化为期望真值表:
LHS |
RHS |
结果 |
---|---|---|
对 |
对 |
对 |
对 |
假 |
假 |
假 |
对 |
假 |
假 |
假 |
假 |
这是一个 logical conjunction (AND) .
实例¶
search(True && False, {"True": true, "False": false}) -> false
search(Number && EmptyList, {"Number": 5, EmptyList: []}) -> []
search(foo[?a == `1` && b == `2`],
{"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]}) -> [{"a": 1, "b": 2}]
Paren表达式¶
paren-expression = "(" expression ")"
A paren-expression
允许用户重写表达式的优先顺序,例如。 (a || b) && c
.
实例¶
search(foo[?(a == `1` || b ==`2`) && c == `5`],
{"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]}) -> []
不是表达式¶
not-expression = "!" expression
A not-expression
否定表达式的结果。如果表达式的结果是一个类真值,则 not-expression
将此值更改为 false
. 如果表达式的结果是一个类假值,则 not-expression
将此值更改为 true
.
实例¶
search(!True, {"True": true}) -> false
search(!False, {"False": false}) -> true
search(!Number, {"Number": 5}) -> false
search(!EmptyList, {"EmptyList": []}) -> true
多选列表¶
multi-select-list = "[" ( expression *( "," expression ) "]"
multiselect表达式用于从JSON哈希中提取元素的子集。multiselect有两个版本,其中一个版本中包含multiselect表达式 {{...}}
还有一个 [...]
. 本节介绍 [...]
版本。在开始和结束字符中是一个或多个用逗号分隔的非表达式。每个表达式都将根据JSON文档进行计算。每个返回的元素将是计算表达式的结果。A multi-select-list
具有 N
表达式将生成一个长度列表 N
. 给出一个多选表达式 [expr-1,expr-2,...,expr-n]
,则计算的表达式将返回 [evaluate(expr-1), evaluate(expr-2), ..., evaluate(expr-n)]
.
实例¶
search([foo,bar], {"foo": "a", "bar": "b", "baz": "c"}) -> ["a", "b"]
search([foo,bar[0]], {"foo": "a", "bar": ["b"], "baz": "c"}) -> ["a", "b"]
search([foo,bar.baz], {"foo": "a", "bar": {"baz": "b"}}) -> ["a", "b"]
search([foo,baz], {"foo": "a", "bar": "b"}) -> ["a", null]
多选哈希¶
multi-select-hash = "{" ( keyval-expr *( "," keyval-expr ) "}"
keyval-expr = identifier ":" expression
A multi-select-hash
表达式类似于 multi-select-list
表达式,但创建的是哈希而不是列表。A multi-select-hash
表达式还需要提供键名,如 keyval-expr
规则。根据以下规则:
keyval-expr = identifier ":" expression
这个 identifier
作为键名和计算 expression
是与关联的值 identifier
关键。
各 keyval-expr
内 multi-select-hash
将对应于所创建哈希中的单个键值对。
实例¶
给出了一个 multi-select-hash
表达 {{foo: one.two, bar: bar}}
数据呢 {{"bar": "bar", {{"one": {{"two": "one-two"}}}}}}
,表达式计算如下:
将创建哈希:
{{}}
一把钥匙
foo
其价值是评估的结果one.two
针对提供的JSON文档:{{"foo": evaluate(one.two, <data>)}}
一把钥匙
bar
其值是对表达式求值的结果bar
针对提供的JSON文档。
最终结果将是: {{"foo": "one-two", "bar": "bar"}}
.
其他示例:
search({foo: foo, bar: bar}, {"foo": "a", "bar": "b", "baz": "c"})
-> {"foo": "a", "bar": "b"}
search({foo: foo, firstbar: bar[0]}, {"foo": "a", "bar": ["b"]})
-> {"foo": "a", "firstbar": "b"}
search({foo: foo, "bar.baz": bar.baz}, {"foo": "a", "bar": {"baz": "b"}})
-> {"foo": "a", "bar.baz": "b"}
search({foo: foo, baz: baz}, {"foo": "a", "bar": "b"})
-> {"foo": "a", "baz": null}
通配符表达式¶
expression =/ "*"
bracket-specifier = "[" "*" "]"
通配符表达式是 *
或 [*]
. 通配符表达式可以返回多个元素,其余表达式将根据通配符表达式返回的每个元素进行求值。这个 [*]
语法应用于列表类型,并且 *
语法适用于哈希类型。
这个 [*]
语法(称为列表通配符表达式)将返回列表中的所有元素。任何后续表达式都将针对每个单独的元素进行计算。给出一个表达式 [*].child-expr
,以及N个元素的列表,则此表达式的计算结果为 [child-expr(el-0), child-expr(el-2), ..., child-expr(el-N)]
. 这被称为 投影 和 child-expr
表达式被投影到结果列表的元素上。
创建投影后,所有后续表达式都将投影到结果列表中。
这个 *
语法(称为哈希通配符表达式)将返回哈希元素值的列表。任何后续表达式都将针对列表中的每个单独元素进行计算(这也称为 投影 )
注意,如果通配符表达式后面的任何后续表达式返回 null
值,则从最终结果列表中省略。
列表通配符表达式仅对JSON数组类型有效。如果列表通配符表达式应用于任何其他JSON类型,则值为 null
返回。
类似地,散列通配符表达式仅对JSON对象类型有效。如果哈希通配符表达式应用于任何其他JSON类型,则值为 null
返回。注意,JSON哈希被显式定义为无序。因此,哈希通配符表达式可以以任何顺序返回与哈希关联的值。实现不需要以任何特定顺序返回哈希值。
实例¶
search([*].foo, [{"foo": 1}, {"foo": 2}, {"foo": 3}]) -> [1, 2, 3]
search([*].foo, [{"foo": 1}, {"foo": 2}, {"bar": 3}]) -> [1, 2]
search('*.foo', {"a": {"foo": 1}, "b": {"foo": 2}, "c": {"bar": 1}}) -> [1, 2]
文字表达式¶
literal = "`" json-value "`"
文本表达式是允许指定任意JSON对象的表达式。这在过滤器表达式和多选散列(创建任意键值对)中很有用,但在允许表达式的任何地方都允许使用。该规范包含了用于JSON的ABNF,实现应该使用现有的JSON解析器来解析文本值。注意 \
字符现在必须在 ``json-value` 这意味着实现需要在将结果字符串传递给JSON解析器之前处理这种情况。
实例¶
search(`"foo"`, "anything") -> "foo"
search(`"foo\`bar"`, "anything") -> "foo`bar"
search(`[1, 2]`, "anything") -> [1, 2]
search(`true`, "anything") -> true
search(`{"a": "b"}`.a, "anything") -> "b"
search({first: a, type: `"mytype"`}, {"a": "b", "c": "d"}) -> {"first": "b", "type": "mytype"}
原始字符串文本¶
raw-string = "'" *raw-string-char "'"
raw-string-char = (%x20-26 / %x28-5B / %x5D-10FFFF) / preserved-escape /
raw-string-escape
preserved-escape = escape (%x20-26 / %28-5B / %x5D-10FFFF)
raw-string-escape = escape ("'" / escape)
原始字符串是允许指定文本字符串值的表达式。计算原始字符串文本表达式的结果是文本字符串值。它是一种更简单的文本表达式形式,它是字符串的特殊大小写形式。例如,以下表达式的值都相同:“foo”::
search(`"foo"`, "") -> "foo"
search('foo', "") -> "foo"
正如您在上面的示例中所看到的,它是指定文本字符串值的常见场景的一种更简洁的形式。
此外,它不执行JSON字符串支持的任何其他处理,包括:
不扩展unicode转义序列
不扩展换行符
不扩展制表符或RFC 4627第2.5节中记录的任何其他转义序列。
search('foo', "") -> "foo"
search(' bar ', "") -> " bar "
search('[baz]', "") -> "[baz]"
search('[baz]', "") -> "[baz]"
search('\u03a6', "") -> "\u03a6"
search('\\', "") -> "\\"
筛选表达式¶
list-filter-expr = "[?" expression "]"
comparator-expression = expression comparator expression
comparator = "<" / "<=" / "==" / ">=" / ">" / "!="
过滤器表达式提供了一种根据与另一个表达式的比较来选择JSON元素的方法。筛选器表达式的计算方法如下:对于数组中的每个元素,计算 expression
对元素不利。如果表达式求值为真值,则该项(全部)将添加到结果列表中。否则,它将从结果列表中排除。过滤器表达式只为JSON数组定义。尝试针对任何其他类型计算筛选器表达式将返回 null
.
比较运算符¶
支持以下操作:
==
,相等性测试。!=
,不平等测试。<
,小于。<=
,小于或等于。>
,大于。>=
,大于或等于。
每个操作的行为取决于每个计算表达式的类型。
下面根据对应的JSON类型定义每个运算符的比较语义:
相等运算符¶
为了 string/number/true/false/null
类型,相等是完全匹配的。A string
等于另一个 string
如果他们有准确的代码点序列。文字值 true/false/null
只等于它们自己的字面值。如果两个JSON对象具有相同的键和值集(给定两个JSON对象),则它们是相等的 x
和 y
,对于每个键值对 (i, j)
在里面 x
,存在等效对 (i, j)
在里面 y
). 如果两个JSON数组的顺序相同,则它们的顺序相同 x
和 y
,每个 i
从 0
直到 length(x)
, x[i] == y[i]
)
排序运算符¶
排序运算符 >, >=, <, <=
是 only 对数字有效。使用比较运算符计算任何其他类型都将生成 null
值,这将导致元素从结果列表中排除。例如,给定:
search('foo[?a<b]', {"foo": [{"a": "char", "b": "char"},
{"a": 2, "b": 1},
{"a": 1, "b": 2}]})
对foo列表中的三个元素进行计算 a < b
. 第一个元素解析为比较 "char" < "bar"
,并且由于这些类型是字符串,因此表达式将导致 null
,因此第一个元素不包含在结果列表中。第二个元素解析为 2 < 1
,这就是 false
,因此第二个元素从结果列表中排除。第三个表达式解析为 1 < 2
评估结果 true
,因此第三个元素包含在列表中。这个表达式的最终结果是 [{{"a": 1, "b": 2}}]
.
实例¶
search(foo[?bar==`10`], {"foo": [{"bar": 1}, {"bar": 10}]}) -> [{"bar": 10}]
search([?bar==`10`], [{"bar": 1}, {"bar": 10}]}) -> [{"bar": 10}]
search(foo[?a==b], {"foo": [{"a": 1, "b": 2}, {"a": 2, "b": 2}]}) -> [{"a": 2, "b": 2}]
函数表达式¶
function-expression = unquoted-string (
no-args /
one-or-more-args )
no-args = "(" ")"
one-or-more-args = "(" ( function-arg *( "," function-arg ) ) ")"
function-arg = expression / current-node / expression-type
current-node = "@"
expression-type = "&" expression
函数允许用户轻松转换和过滤JMESPath表达式中的数据。
数据类型¶
为了支持功能,需要一个类型系统。使用JSON类型:
数字(JSON中的整数和双精度浮点格式)
一串
布尔 (
true
或false
)数组(一个有序的值序列)
对象(键值对的无序集合)
无效的
还有一个附加类型不是JMESPath函数中使用的JSON类型:
表达式(用
&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)
函数支持的数据类型列表包括:
数字(JSON中的整数和双精度浮点格式)
一串
布尔 (
true
或false
)数组(一个有序的值序列)
对象(键值对的无序集合)
无效的
表达式(用
&expression
)
除了最后一项之外,上述所有类型都与JSON提供的类型相对应。
如果一个函数可以为一个输入值接受多个类型,则用 |
. 如果解析的参数与签名中指定的类型不匹配,则 invalid-type
发生错误。
这个 array
类型可以进一步指定对元素类型的要求,如果它们希望强制执行同构类型。子类型由 [type]
,例如,下面的函数签名要求其输入参数解析为数字数组:
return_type foo(array[number] $argname)
作为一种速记 any
用于指示参数可以是任何类型 (array|object|number|string|boolean|null
)
JMESPath函数需要对其输入参数进行类型检查。为函数参数指定无效类型将导致JMESPath错误。
表达式类型,用 &expression
,用于指定不立即求值的表达式。相反,对该表达式的引用将提供给被调用的函数。然后,函数可以根据需要选择应用表达式引用。它在语义上类似于匿名函数。见 sort_by 函数来获取表达式类型的示例用法。
类似地,数组如何使用 array[type]
语法,表达式可以使用 expression->type
语法。这意味着函数参数的已解析类型必须是自身将解析为的表达式 type
.
下面的第一个函数, 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": -1, "bar": "2"}) -> -1
验证已解析参数的类型。在这种情况下
-1
属于类型number
所以它通过了类型检查。使用已解析的参数调用函数::
abs(-1) -> 1
价值
1
函数表达式的解析值abs(foo)
.
以下是评估的相同步骤 abs(bar)
:
根据当前数据计算输入参数:
search(bar, {"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
注意 to_number 定义如下。
现在我们可以计算原始表达式:
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, any $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 |
|
|
ends_with¶
boolean ends_with(string $subject, string $prefix)
返回 true
如果 $subject
以 $prefix
,否则此函数返回 false
.
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
地板¶
number floor(number $value)
如果需要,通过向下舍入返回下一个最小的整数值。
表情 |
结果 |
---|---|
|
1 |
|
1 |
|
1 |
参加¶
string join(string $glue, array[string] $stringsarray)
返回所提供的 $stringsarray
数组使用 $glue
参数作为每个参数之间的分隔符。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
“a,b” |
|
|
“ab” |
|
|
|
|
|
|
钥匙¶
array keys(object $obj)
返回包含所提供对象的键的数组。请注意,由于JSON哈希是继承无序的,因此与提供的对象关联的键 obj
继承无序。实现不需要以任何特定顺序返回键。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
长度¶
number length(string|array|object $subject)
使用以下类型规则返回给定参数的长度:
字符串:返回字符串中代码点的数目
array:返回数组中的元素数
object:返回对象中键值对的数目
鉴于 |
表情 |
结果 |
---|---|---|
n/a |
|
3 |
“当前” |
|
7 |
“当前” |
|
|
|
|
3 |
|
|
0 |
|
|
0 |
|
|
2 |
地图¶
array[any] map(expression->any->any expr, array[any] elements)
应用 expr
中的每个元素 elements
数组并返回结果数组。安 elements
将生成长度为N的返回数组。
与投影不同, ([*].bar
) map()
将包括应用 expr
中的每个元素 elements
数组,即使结果 null
.
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
最大值¶
number max(array[number]|array[string] $collection)
返回在提供的数组参数中找到的最大值。
空数组将产生null的返回值。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
15 |
|
|
“b” |
|
|
|
|
|
|
max_by¶
max_by(array elements, expression->number|expression->string expr)
使用表达式返回数组中的最大元素 expr
作为比较键。返回整个maximum元素。下面是几个使用 people
数组(上面定义的)作为给定的输入。
表情 |
结果 |
---|---|
|
|
|
50 |
|
|
|
<错误:无效类型> |
|
<错误:无效类型> |
合并¶
object merge([object *argument, [, object $...]])
接受0个或多个对象作为参数,并返回一个合并了后续对象的对象。每个后续对象的键/值对将添加到前一个对象。此函数用于将多个对象合并为一个对象。您可以将其视为第一个对象是基对象,而每个后续参数都是应用于基对象的重写。
表情 |
结果 |
---|---|
|
|
|
|
|
|
闽¶
number min(array[number]|array[string] $collection)
返回在提供的 $collection
争论。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
10 |
|
|
“a” |
|
|
|
|
|
|
min_by¶
min_by(array elements, expression->number|expression->string expr)
使用表达式返回数组中的最小元素 expr
作为比较键。返回整个maximum元素。下面是几个使用 people
数组(上面定义的)作为给定的输入。
表情 |
结果 |
---|---|
|
|
|
10 |
|
|
|
|
|
|
not_null¶
any not_null([any $argument [, any $...]])
返回第一个不解析为的参数 null
. 此函数接受一个或多个参数,并按顺序计算它们,直到遇到非空参数。如果所有参数值都解析为 null
,则值为 null
返回。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
[] |
|
|
|
|
|
|
颠倒¶
array reverse(string|array $argument)
颠倒 $argument
.
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
分类¶
array sort(array[number]|array[string] $list)
此函数接受数组 $list
参数,并返回 $list
作为一个数组。
数组必须是字符串或数字的列表。字符串排序基于代码点。不考虑区域设置。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sort_by¶
sort_by(array elements, expression->number|expression->string expr)
使用表达式对数组排序 expr
作为排序键。数组中的每个元素 elements
, the expr
表达式并将结果值用作排序时使用的键 elements
.
如果评估结果 expr
当前数组元素的结果不是 number
或A string
,将发生类型错误。
下面是几个使用 people
数组(上面定义的)作为给定的输入。 sort_by
遵循与 sort
功能。
表情 |
结果 |
---|---|
|
|
|
|
|
|
starts_with¶
boolean starts_with(string $subject, string $prefix)
返回 true
如果 $subject
从 $prefix
,否则此函数返回 false
.
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
总和¶
number sum(array[number] $collection)
返回提供的数组参数的和。
空数组将生成返回值0。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
25 |
|
|
|
|
|
30 |
|
|
0 |
to_array¶
array to_array(any $arg)
数组-返回传入的值。
number/string/object/boolean-返回包含传入参数的单元素数组。
表情 |
结果 |
---|---|
|
|
|
|
|
|
|
|
|
|
to_string¶
string to_string(any $arg)
字符串-返回传入的值。
number/array/object/boolean—对象的JSON编码值。JSON编码器应该发出编码的JSON值,而不添加任何额外的新行。
表情 |
结果 |
---|---|
|
|
to_number¶
number to_number(any $arg)
字符串-返回解析后的数字。任何符合
json-number
支持生产。请注意,浮点数支持将是特定于实现的,但是实现应该至少支持ieee754-2008二进制64(双精度)数字,因为这是普遍可用的并且被广泛使用的。number-返回传入的值。
数组-空
对象-空
布尔值-空
空-空
类型¶
string type(array|object|string|number|boolean|null $subject)
返回给定的 $subject
参数作为字符串值。
返回值必须是以下值之一:
数
一串
布尔
数组
对象
无效的
鉴于 |
表情 |
结果 |
---|---|---|
“福” |
|
“字符串” |
|
|
“布尔值” |
|
|
“布尔值” |
|
|
“空” |
123 |
|
数 |
123.05 |
|
数 |
|
|
“数组” |
|
|
“对象” |
价值观¶
array values(object $obj)
返回对象的值。请注意,由于JSON哈希是继承无序的,因此与提供的对象关联的值 obj
继承无序。实现不需要以任何特定顺序返回值。例如,给定输入:
{"a": "first", "b": "second", "c": "third"}
表达式 values(@)
可能有以下任何返回值:
["first", "second", "third"]
["first", "third", "second"]
["second", "first", "third"]
["second", "third", "first"]
["third", "first", "second"]
["third", "second", "first"]
如果您想要特定的订单,请考虑使用 sort
或 sort_by
功能。
鉴于 |
表情 |
结果 |
---|---|---|
|
|
|
|
|
|
|
|
|
管道表达式¶
pipe-expression = expression "|" expression
管道表达式组合两个表达式,用分隔符分隔 |
性格。它类似于 sub-expression
有两个重要区别:
任何表达式都可以用在右手边。A
sub-expression
限制可在右侧使用的表达式类型。A
pipe-expression
stops projections on the left hand side for propagating to the right hand side. If the left expression creates a projection, it does not apply to the right hand side.
例如,给定以下数据:
{"foo": [{"bar": ["first1", "second1"]}, {"bar": ["first2", "second2"]}]}
表达式 foo[*].bar
给出的结果是:
[
[
"first1",
"second1"
],
[
"first2",
"second2"
]
]
表达的第一部分, foo[*]
,创建投影。此时,剩下的表达式, bar
映射到从创建的列表的每个元素上 foo[*]
. 如果你把 [0]
表达式,则从每个子列表中获取第一个元素。表达式 foo[*].bar[0]
将返回:
["first1", "first2"]
如果你愿意 only 第一个子列表, ["first1", "second1"]
,可以使用 pipe-expression
::
foo[*].bar[0] -> ["first1", "first2"]
foo[*].bar | [0] -> ["first1", "second1"]
实例¶
search(foo | bar, {"foo": {"bar": "baz"}}) -> "baz"
search(foo[*].bar | [0], {
"foo": [{"bar": ["first1", "second1"]},
{"bar": ["first2", "second2"]}]}) -> ["first1", "second1"]
search(foo | [0], {"foo": [0, 1, 2]}) -> [0]