Nested Expressions¶
- JEP
1
- Author
Michael Dowling
- Status
accepted
- Created
27-Nov-2013
Abstract¶
This document proposes modifying the JMESPath grammar
to support arbitrarily nested expressions within multi-select-list
and
multi-select-hash
expressions.
Motivation¶
This JMESPath grammar currently does not allow arbitrarily nested expressions
within multi-select-list
and multi-select-hash
expressions. This
prevents nested branching expressions, nested multi-select-list
expressions
within other multi expressions, and nested or-expressions
within any
multi-expression.
By allowing any expression to be nested within a multi-select-list
and
multi-select-hash
expression, we can trim down several grammar rules and
provide customers with a much more flexible expression DSL.
Supporting arbitrarily nested expressions within other expressions requires:
Updating the grammar to remove
non-branched-expr
Updating compliance tests to add various permutations of the grammar to ensure implementations are compliant.
Updating the JMESPath documentation to reflect the ability to arbitrarily nest expressions.
Nested Expression Examples¶
Nested branch expressions¶
Given:
{
"foo": {
"baz": [
{
"bar": "abc"
}, {
"bar": "def"
}
],
"qux": ["zero"]
}
}
With: foo.[baz[*].bar, qux[0]]
Result:
[
[
"abc",
"def"
],
"zero"
]
Nested branch expressions with nested mutli-select¶
Given:
{
"foo": {
"baz": [
{
"bar": "a",
"bam": "b",
"boo": "c"
}, {
"bar": "d",
"bam": "e",
"boo": "f"
}
],
"qux": ["zero"]
}
}
With: foo.[baz[*].[bar, boo], qux[0]]
Result:
[
[
[
"a",
"c"
],
[
"d",
"f"
]
],
"zero"
]
Nested or expressions¶
Given:
{
"foo": {
"baz": [
{
"bar": "a",
"bam": "b",
"boo": "c"
}, {
"bar": "d",
"bam": "e",
"boo": "f"
}
],
"qux": ["zero"]
}
}
With: foo.[baz[*].not_there || baz[*].bar, qux[0]]
Result:
[
[
"a",
"d"
],
"zero"
]
No breaking changes¶
Because there are no breaking changes from this modification, existing multi-select expressions will still work unchanged:
Given:
{
"foo": {
"baz": {
"abc": 123,
"bar": 456
}
}
}
With: foo.[baz, baz.bar]
Result:
[
{
"abc": 123,
"bar": 456
},
456
]
Modified Grammar¶
The following modified JMESPath grammar supports arbitrarily nested expressions and is specified using ABNF, as described in RFC4234
expression = sub-expression / index-expression / or-expression / identifier / "*"
expression =/ multi-select-list / multi-select-hash
sub-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