Skip to content
CornerTools

JSONPath Tester

Test JSONPath queries against your JSON, with every match and its path, following RFC 9535.

Try
1
1
Matches: 0

Runs a JSONPath query on your JSON and lists what it selects, as values or as Normalized Paths such as $['store']['book'][0], with each match tinted where it sits in the input. Place the cursor on any value to get the path that selects it.

Queries follow RFC 9535, the JSONPath standard published in 2024, and the tool passes every case of the JSONPath Compliance Test Suite. Expressions written for older dialects — Jayway, JMeter, kubectl — get an error that gives the standard way to write them. It runs in your browser: nothing you paste or open is sent anywhere.

How to use it

  • JSONPath query — runs as you type. An error names its column. Try fills in an example query, and the bookstore document of RFC 9535 when the JSON field is empty; Syntax lists everything a query can hold.
  • JSON — typed, pasted, dropped or opened from a file. Matches are tinted by their exact characters, so in minified JSON the value is marked, not the whole line; a match inside another match is covered by the outer tint.
  • At the cursor — the Normalized Path of the value or member the cursor is in; Use as query puts it in the query field.
  • Matches — a JSON array of the selected values, or with Paths of their Normalized Paths, in the order RFC 9535 gives them, with the count beside. Copy and Download carry what is shown.

Values keep their numbers as written: 1.0 stays 1.0, and integers past 253 keep every digit. A key written twice in one object takes its last value, with a warning. A query that runs too long on a large document is stopped.

How a query is evaluated

A query starts at the root, $, and each segment after it takes the nodes selected so far to a new list: a member by name, an item by index, a slice, every child (*), or the children a filter holds for. A descendant segment (..) does the same at every depth, visiting a node before its children and children in document order.

A filter tests each child of a node, with @ standing for that child. Comparisons follow RFC 9535: numbers by value, so 1 == 1.0 holds, compared here exactly from their digits rather than as floating point; strings by Unicode code point; arrays and objects by their contents. A missing member is “Nothing”, which equals only another Nothing, so @.isbn == null is false for a book without an isbn, while !@.isbn is true. Comparing a string with a number is false, never an error.

match() and search() take I-Regexp (RFC 9485), a small regular-expression language every platform can run alike: no \d, \w or lookarounds — write [0-9] — and . matches any character but a line break. A pattern outside I-Regexp makes the test false, as the RFC requires, and a note under the query names it.

A query is checked before it reads the JSON: only a query for one node (names and indexes, such as @.price) can be compared, and functions must get the kind of argument they take, so $[?@.* == 1] is an error rather than an empty result.

Examples on the bookstore document

Titles of the books under 10

JSONPath query
$..book[?@.price < 10].title
Matches
[
  "Sayings of the Century",
  "Moby Dick"
]

2 matches. The filter keeps the books whose price is under 10, and .title then takes each one's title.

Books with an ISBN, as paths

JSONPath query, Paths
$.store.book[?@.isbn]
Matches
[
  "$['store']['book'][2]",
  "$['store']['book'][3]"
]

A query alone inside a filter tests that the member exists, whatever its value.

The last two books' authors

JSONPath query, Paths
$.store.book[-2:].author
Matches
[
  "$['store']['book'][2]['author']",
  "$['store']['book'][3]['author']"
]

A negative start counts from the end; the paths give the index from the start, as Normalized Paths always do.

A title search with an I-Regexp

JSONPath query
$..book[?search(@.title, '[Rr]ing') || length(@.title) < 10].title
Matches
[
  "Moby Dick",
  "The Lord of the Rings"
]

search() looks for the pattern anywhere in the title; length() counts its characters.

JSONPath syntax

What a query can hold, by RFC 9535
SyntaxSelects or means
$The root of the document
@The item a filter is testing
.name ['name']A member by name
[0] [-1]An item by index; negative counts from the end
[1:3] [::2] [::-1]A slice: start, end (not included), step
* [*]Every member or item
..name ..*The same, at every depth
['a','b'] [0,2]Several at once, in order
[?@.price < 10]A filter: the items the test holds for
== != < <= > >=Comparisons
&& || ! ( )And, or, not, grouping
[?@.isbn]Items that have the member
length(@.tags)Characters of a string, items or members
count(@.*)How many nodes a query selects
match(@.id, 'A[0-9]+')The whole string matches an I-Regexp
search(@.title, 'Ring')Part of the string matches
value(@..color)The single value a query selects

Standards

Queries, Normalized Paths and comparisons follow RFC 9535; patterns in match() and search() follow RFC 9485, run as its section 5.3 maps them to JavaScript.

Sources

Reviewed

Frequently asked questions

Before RFC 9535, every library read JSONPath its own way, from Stefan Goessner's 2007 article: Jayway (the Java library JMeter and REST Assured use) added .length(), =~ and in, and kubectl wraps paths in { } templates. The tool answers each with the standard form:

$..book[?(@.author =~ /.*Tolkien/)]
RFC 9535 has no =~; test a pattern with match(@.name, "J.*") or search(@.name, "J") (column 20)
$.store.book.length()
Functions are not methods in RFC 9535: write length(@.items) inside a filter, such as $[?length(@.items) > 2] (column 20)
$..book[?(@.category in ['fiction'])]
"in" is not an RFC 9535 operator; combine comparisons with || and &&, such as @.a == 'x' || @.a == 'y' (column 22)
{.items[*].metadata.name}
kubectl's { } braces wrap a template; write the path alone, starting with $, such as $.items[*] (column 1)

Filters in parentheses, ?(@.price < 10), are standard and work as written.

In RFC 9535, @.tags.length selects a member named length, which arrays do not have. Older dialects read it as the array's size; the standard writes that as $[?length(@.tags) > 2]. The tool notes it when a query using .length selects nothing.
JSONPath selects parts of a document and is the only one of the three with an IETF standard; kubectl and many API test tools take dialects of it. jq is a full programming language for transforming JSON on the command line. JMESPath, used by the AWS CLI, can reshape the result as well as select, with its own specification.

See also