Skip to content
@deckyard/jsonpath

Query syntax

A query starts with $, the document, and applies segments in turn. Each segment takes the nodes so far and selects new ones.

QuerySelects
$.store.bicyclethe member bicycle of store
$['store']['the shop']members by name, any name
$.store.*every member of store
$.book[0], $.book[-1]the first, the last element
$.book[0, 2]elements 0 and 2, in that order
$.book[1:3], $.book[::-1]a slice: [start:end:step], end excluded
$..priceprice anywhere below the root
$..*every node below the root
$.book[?@.isbn]the books that have an isbn
$.book[?@.price < 10]the books cheaper than 10

Names in brackets take single or double quotes and JSON-style escapes (\n, é, \'). A name after a dot is letters, digits and _, plus anything beyond ASCII, and does not start with a digit.

Filters

[?expr] keeps the elements of an array, or the member values of an object, for which expr is true. Inside it, @ is the node being tested and $ still the document.

  • Existence: @.isbn is true when the member exists, even when its value is false or null.
  • Comparisons: == != < <= > >= between literals (numbers, strings, true, false, null), queries that select at most one node, and functions returning a value. 1 == 1.0; strings order by code point; only numbers and strings are ordered; arrays and objects compare by content for ==. A missing node equals only another missing node.
  • Logic: &&, ||, ! and parentheses.
jennifer
import "@deckyard/jsonpath/" as jsonpath;

jsonpath.query($doc, "$..book[?@.category == 'fiction' && !@.isbn]");
jsonpath.query($doc, "$..book[?@.price <= $.limits.max]");

Functions

FunctionTakesGives
length(v)a valuecharacters of a string, elements of an array, members of an object
count(q)a queryhow many nodes it selects
value(q)a querythe one node it selects; nothing for none or several
match(v, re)a string, a patterntrue when the whole string matches
search(v, re)a string, a patterntrue when some part matches
jennifer
jsonpath.query($doc, "$..book[?length(@.title) > 20]");
jsonpath.query($doc, "$..book[?count(@.authors[*]) > 1]");
jsonpath.query($doc, "$..book[?match(@.isbn, '0-[0-9-]+')]");

Patterns are I-Regexp (RFC 9485), a small subset shared by the common regex engines: characters, ., classes [a-z], [^...], Unicode categories \p{L} / \P{Nd}, groups, |, and the quantifiers * + ? {n,m}. There are no \d, \w, \s, lazy quantifiers, backreferences or lookaround; a pattern using them, or any invalid pattern, makes match and search false rather than failing. . matches any character but a line break. Inside a query a backslash is itself escaped: '\\.' is a pattern matching a dot.