JSONPath Syntax Reference

JSONPath operators, filters and recursive descent with IETF RFC 9535 syntax

Interactive JSONPath syntax reference covering RFC 9535 segments — root, child, recursive descent, wildcards, array slices, filter expressions and function extensions — each with an example expression and what it selects. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is RFC 9535?

RFC 9535 is the 2024 IETF standard that finally specifies JSONPath formally, ending years of divergent implementations. It defines the root identifier $, child segments, the descendant segment .., wildcards, array slices, filter selectors and a small set of function extensions like length() and count().

JSONPath is a query language for JSON, the JSON equivalent of XPath for XML. It lets you select nodes from a JSON document with a compact path expression. After years of incompatible implementations, IETF RFC 9535 (2024) standardised the syntax. This reference lists the standard segments and selectors with examples.

How it works

Every JSONPath starts at the root identifier $. You then chain segments that each narrow or expand the set of selected nodes: .name or ['name'] for a child, [*] for every element, .. to descend into all descendants, [0] or [1:3] for array indices and slices, and ?<expr> to filter. Inside a filter, @ refers to the item currently being tested. The engine evaluates the path left to right, producing a node list.

Worked example

Given this document:

{ "store": { "books": [
  { "title": "A", "price": 8 },
  { "title": "B", "price": 15 }
] } }
  • $.store.books[*].title selects ["A", "B"]
  • $..price selects [8, 15] (recursive descent)
  • $.store.books[[email protected] < 10].title selects ["A"] (filter)

Segment quick reference

SyntaxNameWhat it selects
$RootThe entire document
.nameChild (dot)Field named name on current node
['name']Child (bracket)Same as dot notation; required when name has spaces or special chars
[*]WildcardEvery child of the current node
..nameRecursive descentname anywhere in the subtree
[2]IndexThird array element (0-based)
[-1]Negative indexLast array element
[1:4]SliceElements at indices 1, 2, 3 (half-open, Python-style)
[::2]Slice with stepEvery second element
[::-1]Reverse sliceAll elements in reverse order
[email protected]Filter (existence)Items that have an active field
[email protected] > 5Filter (comparison)Items where count is greater than 5
?length(@.tags) > 0Filter (function)Items whose tags array is non-empty

Array slicing in depth

RFC 9535 slices use Python semantics: [start:end:step] where the interval is half-open (start included, end excluded). Negative values count from the end, so [-3:] selects the last three elements. A step of -1 reverses the array. The defaults are start=0, end=length, step=1 when omitted.

For example, on an array of six elements [a, b, c, d, e, f]:

  • [1:4][b, c, d]
  • [-2:][e, f]
  • [::2][a, c, e]

Filter expressions and comparison rules

Filters keep only the nodes for which the expression evaluates to true. Type coercion does not happen: comparing a string to a number always returns false rather than coercing either side, which prevents unexpected matches. Logical operators && and || combine conditions, and existence tests ([email protected]) pass only if the field exists, regardless of its value.

Function extensions available in RFC 9535 include length() (string character count or array size), count() (number of nodes in a nodelist), match() and search() (regex matching), and value() (extracts the value from a single-node nodelist for comparison).

Notes and tips

Recursive descent .. is convenient but scans the whole subtree, so prefer an explicit path on large documents. Filter comparisons are type-aware: comparing a string to a number is simply false rather than an error. Use length() and count() function extensions for size-based filters, e.g. $.items[?length(@.tags) > 0].

Bracket notation ['field'] and dot notation .field are equivalent for simple identifiers, but bracket notation is required whenever the key contains spaces, hyphens, or starts with a digit. When migrating from older JSONPath libraries (such as Goessner 2007 or Jayway), note that RFC 9535 forbids several informal extensions — in particular, the ?(expr) filter shorthand that some libraries supported is now written ?expr inside the standard brackets.