嵌套表达式

JEP

1

作者

道林

状态

认可的

创建

2013年11月27日

摘要

本文件建议修改 JMESPath grammar 支持任意嵌套的表达式 multi-select-listmulti-select-hash 表达。

动机

此JMESPath语法当前不允许在中任意嵌套表达式 multi-select-listmulti-select-hash 表达。这可以防止嵌套的分支表达式 multi-select-list 其他多表达式中的表达式,并嵌套 or-expressions 在任何多重表达式中。

允许任何表达式嵌套在 multi-select-listmulti-select-hash 表达式,我们可以精简几个语法规则,并为客户提供更灵活的表达式DSL。

支持其他表达式中任意嵌套的表达式需要:

  • 正在更新要删除的语法 non-branched-expr

  • 更新符合性测试以添加各种语法置换,以确保实现是兼容的。

  • 更新JMESPath文档以反映任意嵌套表达式的能力。

嵌套表达式示例

嵌套分支表达式

鉴于:

{
    "foo": {
        "baz": [
            {
                "bar": "abc"
            }, {
                "bar": "def"
            }
        ],
        "qux": ["zero"]
    }
}

使用: foo.[baz[*].bar, qux[0]]

结果:

[
    [
        "abc",
        "def"
    ],
    "zero"
]

带有嵌套mutli select的嵌套分支表达式

鉴于:

{
    "foo": {
        "baz": [
            {
                "bar": "a",
                "bam": "b",
                "boo": "c"
            }, {
                "bar": "d",
                "bam": "e",
                "boo": "f"
            }
        ],
        "qux": ["zero"]
    }
}

使用: foo.[baz[*].[bar, boo], qux[0]]

结果:

[
    [
        [
            "a",
            "c"
        ],
        [
            "d",
            "f"
        ]
    ],
    "zero"
]

嵌套or表达式

鉴于:

{
    "foo": {
        "baz": [
            {
                "bar": "a",
                "bam": "b",
                "boo": "c"
            }, {
                "bar": "d",
                "bam": "e",
                "boo": "f"
            }
        ],
        "qux": ["zero"]
    }
}

使用: foo.[baz[*].not_there || baz[*].bar, qux[0]]

结果:

[
    [
        "a",
        "d"
    ],
    "zero"
]

没有突破性的变化

由于此修改没有中断更改,现有的多选表达式仍将保持不变地工作:

鉴于:

{
    "foo": {
        "baz": {
            "abc": 123,
            "bar": 456
        }
    }
}

使用: foo.[baz, baz.bar]

结果:

[
    {
        "abc": 123,
        "bar": 456
    },
    456
]

修正语法

以下修改后的JMESPath语法支持任意嵌套的表达式,并使用ABNF指定,如中所述 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