jsonpathjson-path-expression

JsonPath: get root element depending on first level sub-element


I need all elements (including "id" and all attributes) of the json sample below where "type" has the value "state_machine_state", but only if "type" is on the first level. I don't want the middle element "order_transaction" in the result, although it has "type": "state_machine_state" in the second hierarchy level.

[
  {
    "id": "f45aa035eb424d26a0529d25b3647c32",
    "type": "state_machine_state",
    "attributes": {
      "technicalName": "cancelled",
      "name": "Cancelled",
      "stateMachineId": "7553ad2630044fa589d786135d5000ad",
      "customFields": null,
      "createdAt": "2020-06-05T14:23:30.503+02:00",
      "updatedAt": null,
      "translated": {
        "name": "Cancelled",
        "customFields": []
      },
      "apiAlias": null
    }
  },
  {
    "id": "2d24ed4179824dbe92eee2f3d4f885b1",
    "type": "order_transaction",
    "relationships": {
      "stateMachineState": {
        "data": {
          "type": "state_machine_state",
          "id": "21f236e8955f45d3931fc9e44615088a"
        }
      }
    },
    "meta": null
  },
  {
    "id": "d08e73da41b0473d83ea378a57a2fa1f",
    "type": "state_machine_state",
    "attributes": {
      "technicalName": "completed",
      "name": "Completed",
      "stateMachineId": "7553ad2630044fa589d786135d5000ad",
      "customFields": null,
      "createdAt": "2020-06-05T14:23:30.482+02:00",
      "updatedAt": null,
      "translated": {
        "name": "Completed",
        "customFields": []
      },
      "apiAlias": null
    },
    "meta": null
  }
]

With the query below I get all three elements

$..[?(@.type == 'state_machine_state')]

I just can't manage to select only the first level elements.

Could anyone please help?


Solution

  • Sometimes it helps to take a step back and think another way. With this query I get exactly what I want:

    $..[?(@.type == 'state_machine_state' && @.attributes)]
    

    The elements I need have attributes, the others don't, so I just check for that in the filter.