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