Processing JSON data with JMESPath Part 1 - Basic Expressions and Projections

Image credit: Unsplash

JMESPath has made the processing of complex JSON objects a tad bit easier. A JSON document is deconstructed using simple yet very powerful expressions. The witers of JMESPath claim it is an ABNF grammar with a complete specification.

To follow this illustration, you can play around with these expressions on the playground provided on the library’s home page.

Basic Expressions

Accessing Nested Objects (Sub-expressions)

Using this object;

{
    "level_one_key1":{
        "level_two_key1":"level_two_value1",
        "level_two_key2":"level_two_value2"
    },
    "level_one_key2":{

    }
}

to access values in the first nesting level, we just need to call the desired data’s key as follows

level_one_key1

which gives us

{
  "level_two_key1": "level_two_value1",
  "level_two_key2": "level_two_value2"
}

For values in the second nesting, we just call them using the combine level one and two keys as follows;

level_one_key1.level_two_key1

and get:

"level_two_value1"

If you use a key that does not exist, the result will be:

null

Accessing Objects using Indices

To access the members of an array, indexing can be used. For example, to get "b" from:

["a","b",{"a":"b"},"4"]

, use:

[1]

and:

[2]

and so on.

Slicing Array Objects using Indices

Using the array from previous example,

[1:3]

gives

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

Wildcard Expressions - List and Slice Projections

A wildcard expression projects the values of a JSON object belonging to a value to a list array. For example; Given:

{
  "items": [
    {"id": "3", "colour": "blue"},
    {"id": "4", "colour": "purple"},
    {"id": "5", "colour": "peach"},
    {"colour": "green"}
  ],
  "towns": {"name": "Thika"}
}

we can project all members of "items" to a list array as follows;

items[*]

to get:

[
  {
    "id": "3",
    "colour": "blue"
  },
  {
    "id": "4",
    "colour": "purple"
  },
  {
    "id": "5",
    "colour": "peach"
  },
  {
    "colour": "green"
  }
]

Note that if "items" was nested as a value, like:

{
    "data":{
  "items": [
    {"id": "3", "colour": "blue"},
    {"id": "4", "colour": "purple"},
    {"id": "5", "colour": "peach"},
    {"colour": "green"}
  ],
  "towns": {"name": "Thika"}
},
    "date":"values"
}

then the same projection as above should be achieved as follows;

data.items[*]

We can limit the resultant list to just IDs as follows data.items[*].id or colours like data.items[*].colour.

Note what happens to the last record of "items" when .id is replaced with .colour.

The list can be sliced as desired like data.items[0:2].colour. Note that the slicing happens first.

Conclusion

This section covers the basics and projections of JSON data using JMESPath.

Part 2 goes into detail about filtering.

Ian Njari
Ian Njari
Software Engineer

My interests include Data Engineering, AI in Consumer Technology and MLOps

Related