JSONPath examples: how to query JSON with RFC 9535 filters, slices and functions

Start every query with $, step into keys with .name or ['name'], use [*] for every item, .. to search at any depth, and [?...] to filter. RFC 9535 adds length(), count(), match(), search() and value() for filters.

JSONPath is a small query language for picking values out of a JSON document. A query like $.users[*].email walks from the root to every user and returns each email, so you don't have to scroll through a 5,000 line API response by hand. Since 2024 it has a real standard, RFC 9535, which means one query can give the same answer in every tool that follows it.

By TechCompare · Updated

Topic
JSONPath queries
jsonpath
Category
Querying
JSON knowledge base

How this is calculated

Before RFC 9535, each library had its own dialect. Some ran script expressions inside filters, some returned single values instead of lists, and a few disagreed on what .. should match. The standard fixed that. A query always returns a list of nodes, and each node has a normalized path, like $['users'][0]['email'], that points at exactly one place. Filters work on a small expression language with comparisons, && || and !, so nothing in a query runs as code. Numbers compare by value. Strings compare by Unicode code points. A comparison between different types, like a number and a string, is simply false instead of an error. The five functions cover the common needs: length() counts characters, items or keys, count() counts the nodes a query finds, match() and search() test a string against a regular expression, and value() turns a one node result into a value you can compare.

Verdict

Use simple paths for known locations and filters for questions. $.orders[0].total reads one value. $.orders[?@.total > 100].id answers a question about every order. Reach for .. only when you don't know how deep a key sits, since it visits every value in the document. Wrap keys with spaces or symbols in brackets and quotes, like $['first name'], and check every query against a real sample before you rely on it in code.

More JSON scenarios

Frequently asked questions

What's the difference between $.a.b and $..b?
$.a.b follows one exact route: the b key inside the a key at the root. $..b looks for a b key at any depth, inside any object or array, and returns every match it finds. Use the exact route when you know the shape, and .. when you don't, since .. has to visit every value in the document.
How do I filter an array by a value in JSONPath?
Use a filter selector with @ for the current item. $.products[?@.price < 10] returns every product cheaper than 10. Combine tests with && and ||, like $.products[?@.price < 10 && @.stock > 0], and use ! to negate one. A filter that only names a key, like [?@.discount], keeps the items that have that key.
Why does my old JSONPath query fail in an RFC 9535 tool?
Older libraries accepted things the standard leaves out, like script expressions such as [(@.length-1)], ?() filters with JavaScript inside, or a trailing .length. Rewrite them with standard syntax: [-1] for the last item, [?...] without the parentheses for filters, and length() for sizes. A good tool points at the position of the first character it couldn't read.
Does a JSONPath query keep large numbers exact?
That depends on the tool, not the query. A tool built on JSON.parse reads 9007199254740993 as 9007199254740992 before the query even runs. The TechCompare JSON tool reads numbers by their written digits, so results and comparisons keep the exact value.