JSONPath Tester
Type a JSONPath expression and see the result instantly. Every match is highlighted inside your JSON and listed with its exact normalized path, so you can debug filters, slices and recursive queries in seconds.
How to use the JSONPath Tester
- Paste your JSON into the left editor, upload a file, or keep the bookstore sample.
- Type a JSONPath expression starting with
$in the query box, or click one of the examples. - Watch the matches light up in the Highlighted tab. The counter shows how many nodes matched.
- Switch tabs to see the result as a JSON array or the list of normalized paths.
- Copy the result or the paths with one click and use the expression in your code.
JSONPath syntax cheat sheet
| Syntax | Meaning | Example |
|---|---|---|
$ | The root of the document | $ |
.name / ['name'] | Child property (use brackets for names with spaces or symbols) | $.store['bicycle'] |
..name | Recursive descent: the property at any depth | $..price |
* | Wildcard: every property or array element | $.store.*, $..book[*] |
[n] | Array index, zero based; negative counts from the end | $..book[0], $..book[-1] |
[a,b] | Union of several indexes or names | $..book[0,2], $['a','b'] |
[start:end:step] | Array slice; end is exclusive, all parts optional | $..book[1:3], $..book[::2], $..book[-2:] |
[?(expr)] | Filter: keeps children for which the expression is true; @ is the current child | $..book[?(@.price < 10)] |
[?(@.key)] | Existence test | $..book[?(@.isbn)] |
== != < <= > >= | Comparisons (numbers with numbers, strings with strings) | [?(@.category == 'fiction')] |
&& || ! and ( ) | Logical and, or, not, grouping | [?(@.price > 5 && [email protected])] |
=~ /re/i | Regular expression test (Jayway/Goessner extension) | [?(@.author =~ /^J/)] |
length() count() match() search() value() | RFC 9535 functions | [?(length(@.tags) > 2)], [?match(@.code, '[A-Z]{3}')] |
How the evaluation works
A JSONPath expression is a chain of segments. Evaluation starts with a list containing just the root value. Each segment takes every node in the current list and replaces it with the nodes its selectors pick out, so the list can grow (wildcards, recursive descent) or shrink (names, indexes, filters). The final list is the result, always in document order. This tester follows RFC 9535: a missing property or an out-of-range index simply yields no match instead of an error, and comparisons between different types (such as "10" < 20) are false.
Inside a filter, @ refers to the child being tested and $ still refers to the document root, which lets you compare against other values, for example $..book[?(@.price > $.expensive)]. A comparison operand must select a single value; a path that matches nothing compares as "nothing", which is only equal to another "nothing".
Differences between JSONPath implementations
- Filter syntax. Goessner's original syntax and Jayway (Java) use
[?(@.a)]. RFC 9535 also accepts[[email protected]]. Both work here. - Script expressions such as
[(@.length-1)]ran arbitrary JavaScript in early libraries and were dropped from the standard. Use[-1]instead. - Result shape. Some libraries return a single value instead of an array when exactly one node matches. Standard JSONPath always returns a list (node list), which is what the Result tab shows.
- Regex.
=~is a Jayway extension; the portable RFC 9535 equivalents arematch()(whole string) andsearch()(substring).
Frequently asked questions
What is JSONPath?
JSONPath is a query language for selecting values inside a JSON document, similar to XPath for XML. It was introduced by Stefan Goessner in 2007 and standardized by the IETF as RFC 9535 in 2024. An expression always starts at the root $ and walks down with segments like .store.book[0].
What is the difference between . and .. in JSONPath?
A single dot selects a direct child, so $.store.book only looks one level down at a time. Two dots are recursive descent: $..author finds every author property at any depth of the document.
How do I write a JSONPath filter?
Use [?( )] with @ standing for the current item, for example $.store.book[?(@.price < 10)] or $..book[?(@.category == 'fiction' && @.price > 10)]. RFC 9535 also allows the form without parentheses: [[email protected] < 10]. A path on its own, like [?(@.isbn)], keeps items that have that property.
How do I get the last element of an array?
Use a negative index: $..book[-1] returns the last book. Slices also accept negatives: [-2:] returns the last two items. The old script syntax [(@.length-1)] is not part of RFC 9535 and is not supported here.
What is a normalized path?
A normalized path is the unique, fully bracketed location of one matched value, such as $['store']['book'][2]['title']. It is the format defined by RFC 9535 and is handy for logging or for pointing at exactly one value.
Why does my expression return nothing?
Common causes are a typo in a property name (names are case-sensitive), using . instead of .. for a deeper property, comparing a number to a string ("10" is not equal to 10), or a filter applied to an object when you meant its array. Check the Highlighted tab to see where the data really is.
Is my JSON sent to a server?
No. The JSONPath engine is written in JavaScript and runs inside your browser, so your data never leaves your device.