管道表达式¶
- JEP
4
- 作者
道林
- 状态
认可的
- 创建
2013年12月7日
摘要¶
本文档建议在后续表达式中添加对管道表达式的支持。
动机¶
当前的JMESPath语法允许在表达式中的不同点进行投影。但是,目前还无法将投影结果作为列表进行操作。
下面的例子说明了不可能对投影的结果进行操作(例如,获取投影的第一个匹配)。
鉴于:
{
"foo": {
"a": {
"bar": [1, 2, 3]
},
"b": {
"bar": [4, 5, 6]
}
}
}
表达式:
foo.*.bar[0]
结果将是每个元素的0 bar
:
[1, 4]
通过添加过滤器,我们可以将一个表达式的结果传递给另一个表达式,对投影(或任何表达式)的结果进行操作。
表达式:
foo.*.bar | [0]
结果:
[1, 2, 3]
这不仅使我们能够对投影结果进行操作,而且管道表达式还可以用于将复杂表达式分解为更小、更易于理解的部分。
修正语法¶
以下修改后的JMESPath语法支持管道表达式。
expression = sub-expression / index-expression / or-expression / identifier / "*"
expression =/ multi-select-list / multi-select-hash / pipe-expression
sub-expression = expression "." expression
pipe-expression = expression "|" expression
or-expression = 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 / "*") "]" / "[]"
number = [-]1*digit
digit = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" / "0"
identifier = 1*char
identifier =/ quote 1*(unescaped-char / escaped-quote) quote
escaped-quote = escape quote
unescaped-char = %x30-10FFFF
escape = %x5C ; Back slash: \
quote = %x22 ; Double quote: '"'
char = %x30-39 / ; 0-9
%x41-5A / ; A-Z
%x5F / ; _
%x61-7A / ; a-z
%x7F-10FFFF
注解
pipe-expression
has a higher precendent than the or-operator
符合性测试¶
[{
"given": {
"foo": {
"bar": {
"baz": "one"
},
"other": {
"baz": "two"
},
"other2": {
"baz": "three"
},
"other3": {
"notbaz": ["a", "b", "c"]
},
"other4": {
"notbaz": ["d", "e", "f"]
}
}
},
"cases": [
{
"expression": "foo.*.baz | [0]",
"result": "one"
},
{
"expression": "foo.*.baz | [1]",
"result": "two"
},
{
"expression": "foo.*.baz | [2]",
"result": "three"
},
{
"expression": "foo.bar.* | [0]",
"result": "one"
},
{
"expression": "foo.*.notbaz | [*]",
"result": [["a", "b", "c"], ["d", "e", "f"]]
},
{
"expression": "foo | bar",
"result": {"baz": "one"}
},
{
"expression": "foo | bar | baz",
"result": "one"
},
{
"expression": "foo|bar| baz",
"result": "one"
},
{
"expression": "not_there | [0]",
"result": null
},
{
"expression": "not_there | [0]",
"result": null
},
{
"expression": "[foo.bar, foo.other] | [0]",
"result": {"baz": "one"}
},
{
"expression": "{\"a\": foo.bar, \"b\": foo.other} | a",
"result": {"baz": "one"}
},
{
"expression": "{\"a\": foo.bar, \"b\": foo.other} | b",
"result": {"baz": "two"}
},
{
"expression": "{\"a\": foo.bar, \"b\": foo.other} | *.baz",
"result": ["one", "two"]
},
{
"expression": "foo.bam || foo.bar | baz",
"result": "one"
},
{
"expression": "foo | not_there || bar",
"result": {"baz": "one"}
}
]
}]