复杂 JSON 和 Ansible JSON_QUERY 语法

Complex JSON and Ansible JSON_QUERY syntax

我有复杂的 JSON 格式的结果,并且正在努力从中提取值。 我测试了 JSONpath 在线评估器 https://jsonpath.com/,我可以在其中简单地键入

$.[*].toPort

并获取请求的变量列表。

我尝试在 Ansible 中使用相同的语法,但得到的是空列表。

- name: JSON test
  hosts: localhost
  gather_facts: no

  vars:
    jsoncontent:
                {
                        "infraAccPortP": {
                            "attributes": {
                                "annotation": "",
                                "childAction": "",
                                "descr": "",
                                "nameAlias": "",
                                "ownerKey": "",
                                "ownerTag": "",
                                "status": "",
                                "uid": "15374"
                            },
                            "children": [
                                {
                                    "infraHPortS": {
                                        "attributes": {
                                            "annotation": "",
                                            "uid": "8927"
                                        },
                                        "children": [
                                            {
                                                "infraPortBlk": {
                                                    "attributes": {                                                  
                                                        "fromPort": "41",
                                                        "toPort": "41",
                                                        "uid": "8927"
                                                    }
                                                }
                                            }
                                        ]
                                    }
                                },
                                {
                                    "infraHPortS": {
                                        "attributes": {
                                            "annotation": "",
                                            "uid": "8927"
                                        },
                                        "children": [
                                            {
                                                "infraPortBlk": {
                                                    "attributes": {
                                                        "fromPort": "42",
                                                        "toPort": "42",
                                                        "uid": "8927"
                                                    }
                                                }
                                            }
                                        ]
                                    }
                                }
                            ]
                        }
                    }

  tasks:
    - name: show jsoncontent
      debug:
        var: jsoncontent

    - name: Show just toPort values
      debug: 
        msg: "{{ jsoncontent | json_query(jmesquery)    }}"
      vars:
        jmesquery: "[*].toPort"

对如何调整查询以获得预期结果有帮助吗?这有点令人沮丧,因为没有太多关于如何在 Ansible

中实现 json_query 的文档

下面的任务完成工作

    - name: Show just toPort values
      debug: 
        msg: "{{ jsoncontent.infraAccPortP.children | json_query(jmesquery) }}"
      vars:
        jmesquery: "[].infraHPortS.children[].infraPortBlk.attributes.toPort"

给予

  msg:
  - '41'
  - '42'

Q: "Ansible implementation doesn't allow wildcard searches?"

答:自 2.10 以来,implementation. (This filter moved to ansible-collections/community.general 似乎没有什么特别之处。)


Q: "Just confused why I got the same result with much shorter syntax in that online checker."

A:我认为问题在于检查器是如何实现的。 jq 这种方式也行不通。例如

shell> cat data.json | jq .jsoncontent.infraAccPortP.children[].infraHPortS.children[].infraPortBlk.attributes.toPort
"41"
"42"

“检查器”查询崩溃

shell> cat data.json | jq .[*].toPort
jq: error: syntax error, unexpected '*' (Unix shell quoting issues?) at <top-level>, line 1:
.[*].toPort  
jq: 1 compile error

,或者给出空结果

shell> cat data.json | jq .[].toPort
null