JSONPath Tester
Query JSON with JSONPath as standardised in RFC 9535 (IETF Standards Track, February 2024). Full filter expressions, the five built-in functions, and Normalized Paths for every match — verified against the official compliance test suite.
Enter a JSONPath expression above
What is JSONPath?
JSONPath is a query language for JSON, analogous to XPath for XML. It lets you describe a path through a JSON document with a compact syntax: instead of writing nested loops and conditionals to extract specific values, you write a single path expression.
For example, given an API response with a list of users, $.users[*].email extracts every email address. $.users[?(@.role=="admin")].name extracts the names of admin users. $..price finds every "price" field anywhere in the document, no matter how deeply nested.
JSONPath was originally specified by Stefan Goessner in 2007 and has been implemented widely — in nearly every programming language, in jq (with adjusted syntax), in tools like Postman, and now in the IETF RFC 9535 standardization. Our tester implements the Goessner subset that all libraries agree on.
Complete JSONPath syntax reference
$ Root
The root of the JSON document. Every JSONPath starts with $.
.name Dot child
Access an object property by name. $.user.name returns the name field of the user object.
['name'] Bracket child
Access by name with brackets — needed for keys with special characters: $['user-name'].
[*] Wildcard
All elements of an array or all values of an object. $.users[*] returns every user.
.. Recursive descent
Match at any depth. $..price finds every "price" property anywhere in the tree.
[2] Array index
0-based index into an array. $.users[0] returns the first user. Negative indexes count from the end.
[1:3] Slice
Range of indexes (like Python slices). $.users[0:3] returns the first three users.
[?()] Filter
Filter array elements by predicate. $.users[?(@.age > 18)] returns users older than 18.
[a,b] Union
Multiple keys at once. $['name','email'] returns both the name and email fields.
JSONPath examples in practice
Here are real-world JSONPath expressions for common tasks:
$.data.items[*].id— extract all item IDs from a paginated response$..error— find every error message anywhere in a nested response$.users[?(@.active==true)].email— emails of all active users$.products[?(@.price > 100 && @.stock > 0)].name— names of in-stock products over $100$.orders[-3:]— the last 3 orders$.users[*].address.city— the city of every user$..book[?(@.isbn)]— every book that has an ISBN field$['key with spaces']['nested key']— accessing keys with special characters
FAQ — Jsonpath Tester
. and ..?$.a.b only finds b directly under a. $..b finds b anywhere in the tree.@ to refer to the current array element. $.users[?(@.age > 18)] iterates over each user and tests whether their age field exceeds 18. Operators supported: ==, !=, <, <=, >, >=.$.. return so many results?$.. alone matches every node in the document — including the root, every object, every array, every value. Almost always you want to chain a property after: $..name finds every "name" field.$['key.with.dots'] instead of $.key.with.dots (which the parser would interpret as nested access).$.users[?(@.role=="admin")] selects users whose role equals admin. There's no direct "find a value" — JSONPath always selects from a position in the tree.[-1] is the last element, [-2] the second-to-last, and so on. For slices, [-3:] means "the last three elements".703/703 on the official RFC 9535 test suite
JSONPath existed for twenty years as a blog post before it became a standard, and implementations drifted apart badly. RFC 9535 fixed the grammar and, importantly, the semantics. This tester is scored against the JSONPath Compliance Test Suite maintained by the working group:
| Category | Result |
|---|---|
| Evaluation — the query returns the right nodes | 456 / 456 |
| Rejection — invalid queries are refused | 247 / 247 |
The second row matters as
much as the first. RFC 9535 §2.1 requires a conforming implementation to reject a query that
does not match the grammar rather than guess at it, so $[], $..,
$[0,] and $[@.a] produce an error with a position, not a silently different
answer.
Where RFC 9535 differs from older implementations
Comparisons are strictly typed
$[?@.a=="1"] matches the string "1" and not the number
1. Many pre-standard implementations coerced, which quietly returned extra rows.
Five built-in functions
length(), count(), value(), and match() /
search() using I-Regexp (RFC 9485). Function arguments are type-checked at parse
time, so a mistyped call is an error rather than a false result.
Normalized Paths
Every match is reported with its Normalized Path (§2.7) — the canonical, unambiguous location of that node, which you can feed back in as a query.
Specifications
- RFC 9535 — JSONPath: Query Expressions for JSON — S. Gössner, Ed., G. Normington, Ed., C. Bormann, Ed., February 2024. IETF Standards Track. §2.3 Selectors, §2.3.5 Filter Selector, §2.4 Function Extensions, §2.7 Normalized Paths.
- RFC 9485 — I-Regexp: An Interoperable Regular Expression Format
— C. Bormann, T. Bray, 2023. The regex dialect used by
match()andsearch(). - RFC 9535 §2.2 — Root Identifier
— why a query must begin with
$. - RFC 8259 (STD 90) — JSON — the data model JSONPath queries.
Where to go next
- Schema Validator — describe the shape you are querying, rather than probing it
- JSON Patch — JSON Pointer addresses one node the way a Normalized Path does
- Formatter — format a document before writing queries against it
- Glossary — segments, selectors, singular queries and Normalized Paths defined
- All tools