JSONpath

JSONpath is an expression language used to filter JSON Data. It is also used within Kubernetes (kubectl) to filter the output when using the “-o=jsonpath” option.

To get some real practice, I highly suggest following the free course by KodeKloud. Most of the information listed here is lifted from the course.

JSON primer

This is a quick primer on some JSON terms.

Dictionary

{
  "danse_macabre": {
    "manufacturer": "Intamin",
    "type": "Dynamic Motion Stage"
  }
}

To get for example the type of danse_macabre here, you would use the jsonpath $.danse_macabre.type.

Lists

[ 
  "danse_macabre",
  "pagode",
  "fata_morgana",
  "pirana",
  "de_vliegende_hollander",
  "max_en_moritz"
]

In order to get:

  • The first element: $[0] which will return [ "danse_macabre" ]
  • The third element: $[2] which will return [ "fata_morgana" ]
  • The second and the fifth element: $[2,4] which will return [ "pagode", "de_vliegende_hollander"]
  • Get the first to the third element: $[0:2], which will return [ "danse_macabre","pagode", "fata_morgana" ]
  • To get the last element either use $[-1:0] or $[-1:]
  • To get the last three elements: $[-3:]

Lists and dictionaries combined

{
  "rides": {
    "rollercoasters": [
      {
        "name": "De Vliegende Hollander",
        "manufacturer": "Kumbak",
        "type": "Water coaster"
      },
      {
        "name": "Max en Moritz",
        "manufacturer": "Mack Rides",
        "type": "Powered Coaster"
      }
    ],
    "flatrides": [
      {
        "name": "Danse Macabre",
        "manufacturer": "Intamin", 
        "type": "Dynamic Motion Stage"
      }
    ]
  }
}

In order to get:

  • The manufacturer of the first rollercoaster: $.rides.rollercoasters[1].manufacturer

Criteria

[
  4,
  8,
  15,
  16,
  23,
  42  
]

In order to get:

  • All numbers greater than 20: $[ > 20]
  • Get each item in the list > 20: $[?(>20)]
  • Each item in the list => 20: $[?( @ > 40)]
  • Item equal to 20: $[?(@ == 20)]
  • Item not equal to 20: $[?(@ != 20)]

Wildcards

{
  "danse_macabre": {
    "manufacturer": "Intamin",
    "type": "Dynamic Motion Stage"
  },
  "de_vliegende_hollander": {
    "manufacturer": "Kumbak",
    "type": "Water Coaster"
  }
}

In order to get:

  • Get all types: $.*.type, which will give [ "Dynamic Motion Stage", "Water Coaster" ]
{
  "rides": {
    "rollercoasters": [
      {
        "name": "De Vliegende Hollander",
        "manufacturer": "Kumbak",
        "type": "Water coaster"
      },
      {
        "name": "Max en Moritz",
        "manufacturer": "Mack Rides",
        "type": "Powered Coaster"
      }
    ],
    "flatrides": [
      {
        "name": "Danse Macabre",
        "manufacturer": "Intamin", 
        "type": "Dynamic Motion Stage"
      }
    ]
  }
}

In order to get:

  • The first rollercoasters manufacturer: $.rides.rollercoasters[0].manufacturer
  • To get all the manufacturers of rollercoasters: $.rides.rollercoasters[*].manufacturer
  • To get the names of all rides:$.rides[*].name

Kubernetes

Here are some examples of how to do something with jsonpath in combination with kubectl:

  • Get name of all nodes: kubectl get nodes -o=jsonpath='{.items[*].metadata.name}
  • Get architecture of all nodes: kubectl get nodes -o=jsonpath={.items[*].status.nodeInfo.architecture}
  • Get the nodes + the amount of CPU capacity, on a new line: kubectl get nodes -o=jsonpath='{.items[*].metadata.name}{"\n"}{.items[*].status.capacity.cpu}

Loops

To range over items, this can be used instead:

'{range .items[*]}
    {.metadata.name} {"\t"} {.status.capacity.cpu}{"\n"}
{end}'
```

The above information is mainly from the KodeKloud course I have linked above, the following is from the cheat sheet created by [mackoj](https://gist.github.com/mackoj/5786f8b95da0a82e8e003f444c4295bf).
## Syntax
Within JSONPath, you will often start your expressions with `$.`, as this indicates the root (highest) element. However,
some clients might omit this.

     $.store.book[0].title              
     store.book[0].title                # With implicit "$."
     
     $['store']['book'][0]['title']     # Alternative notation similar to scripting languages

## Tree Traversal

     $.parentNode.childNode.field       # XPath: /parentNode/childNode/@field (content of "field" of all "childNode"s of "parentNode")
     $..anyChildNode                    # XPath: //anyChildNode (all children at any depth named "anyChildNode"
     $.parentNode.*                     # XPath: /parentNode/* (all children below)

## Array Access

     $.myList[0]            # first element
     $.myList[-1]           # last element
     $.myList[2:3]          # range
     $.myList[0,4,5]        # selection

## Filtering

     $.customer[?(@.car)]                      # Only "customer"s that have attribute "car"
     $.customer[?(@.car == 'Ford Fiesta')]     # Only "customer"s with "Ford Fiesta"s
     $.customer[?(@.age > 18)]                 # Only adults

## Complex Conditions


     $.customer[?(@.age > 18 || @.car == 'Ford Fiesta')]     # logical or
     $.customer[?(@.age < 18 && @.hobby == 'Biking' )]       # logical and

## Output Mapping

     $.[].{Name:name, Age:age, Hobbies:details.hobbies}        # Mapping fields/nested fields to new set

Posted on Friday, 7 February 2025