Warm tip: This article is reproduced from serverfault.com, please click

JMESPath Path Where Key Might Not Exist

发布于 2021-01-08 17:51:27

I have a weird JSON construct (I cannot provide the actual data for security reasons, but I can provide the structure, which is all that really matters).

Given the following structure:

[
  {
    "a": {
      "b": {
        "c": "d"
      }
    }
  },
  {
    "b": {
      "c": "d"
    }
  },
]

I need to have a way to always get to c without knowing if the path contains a or not. Something like:

[].*.b.c.d

or

[].a?.b.c.d

Any ideas?

For reference, I am using the jmespath library for python.

Questioner
Eagle4
Viewed
0
β.εηοιτ.βε 2021-01-10 05:57:40

Given the JSON:

[
  {
    "a": {
      "b": {
        "c": "d (of a.b.c)"
      }
    }
  },
  {
    "b": {
      "c": "d (of b.c)"
    }
  },
  {
    "z": {
      "b": {
        "c": "d (of z.b.c)"
      }
    }
  }
]

You can use a combination of the or expression (||) and the flatten operator ([]) to achieve what you want.

So the expression:

[][*.b || b] [] []

On the above JSON would yield:

[
  {
    "c": "d (of a.b.c)"
  },
  {
    "c": "d (of b.c)"
  },
  {
    "c": "d (of z.b.c)"
  }
]

Note that we have to use the flatten operator twice because of the structure that, sometimes has two levels and sometimes three.


And if you just want the value of c:

[][*.b || b] [] [].c

Will yield:

[
  "d (of a.b.c)",
  "d (of b.c)",
  "d (of z.b.c)"
]