Documentation
JSPATH
JSPATH is a domain-specific language (DSL) that allows you to find and extract data from JSON documents. With JSPATH, you can select JSON elements to get the data they contain.
Example data:
{
  "automobiles": [
    { "maker": "Nissan", "model": "Teana", "year": 2011 },
    { "maker": "Honda", "model": "Jazz", "year": 2010 },
    { "maker": "Honda", "model": "Civic", "year": 2007 },
    { "maker": "Toyota", "model": "Yaris", "year": 2008 },
    { "maker": "Honda", "model": "Accord", "year": 2011 }
  ],
  "motorcycles": [{ "maker": "Honda", "model": "ST1300", "year": 2012 }]
}
Example path to data — .automobiles{.maker === "Honda" && .year > 2009}.model
Result:
["Jazz", "Accord"]
Predicates
JSPATH predicates allow you to write very specific rules for the elements you want to select when building a path expression. Predicates are filters that limit the elements selected by the location path. There are two possible types of predicates: object and positional predicates.
Object Predicates
Object predicates can be used in a path expression to filter a subset of elements according to boolean expressions operating on the properties of each element. All object predicates are enclosed in curly braces ({ and }).
In JSPATH, the following basic expressions can be used within an object predicate:
  • numeric literals (e.g., 1.23)
  • string literals (e.g., "John Gold")
  • boolean literals (true and false)
  • literal null (null)
  • nested paths (e.g., .nestedProp.deeplyNestedProp)
  • nested predicates (e.g., .prop{.nestedProp{.deeplyNestedProp{.stillMore || .yetAnother} || .otherDeeplyNested}})
Additionally, the following types of operators are valid within an object predicate:
  • comparison operators
  • string comparison operators
  • logical operators
  • arithmetic operators

Comparison Operators

operator
description
example
==
returns true if both operands are equal
.books{.id == "1"}
===
returns true if both operands are strictly equal without type conversion
.books{.id === 1}
!=
returns true if operands are not equal
.books{.id != "1"}
!==
returns true if operands are not equal and/or not of the same data type
.books{.id !== 1}
>
returns true if left operand is greater than right
.books{.id > 1}
>=
returns true if left operand is greater than or equal to right
.books{.id >= 1}
<
returns true if left operand is less than right
.books{.id < 1}
<=
returns true if left operand is less than or equal to right
.books{.id <= 1}
JSPATH uses the following rules for comparing arrays and objects of different types:
  • if both compared operands are arrays, the comparison will be true if there exists an element in the first array and an element in the second array such that the result of comparing these two elements is true
  • if one operand is an array and the other is not, the comparison will be true if there exists an element in the array such that the result of comparing this element and the other operand is true
  • primitives are compared as regular JavaScript primitives

String Comparison Operators

If both operands are strings, additional comparison operators are available:
operator
description
example
==
returns true if both strings are equal
.books{.title == "clean code"}
^==
case-sensitive; returns true if left operand starts with right
.books{.title ^== "Javascript"}
^=
case-insensitive; returns true if left operand starts with right
.books{.title ^= "javascript"}
==^
case-sensitive; returns true if right operand starts with left
.books{.title ==^ "Javascript"}
=^
case-insensitive; returns true if right operand starts with left
.books{.title =^ "javascript"}
$==
case-sensitive; returns true if left operand ends with right
.books{.title $== "Javascript"}
$=
case-insensitive; returns true if left operand ends with right
.books{.title $= "javascript"}
==$
case-sensitive; returns true if right operand ends with left
.books{.title ==$ "Javascript"}
=$
case-insensitive; returns true if right operand ends with left
.books{.title =$ "javascript"}
*==
case-sensitive; returns true if left operand contains right
.books{.title *== "Javascript"}
*=
case-insensitive; returns true if left operand contains right
.books{.title *= "javascript"}
==*
case-sensitive; returns true if right operand contains left
.books{.title ==* "Javascript"}
=*
case-insensitive; returns true if right operand contains left
.books{.title =* "javascript"}

Logical Operators

operator
description
example
&&
returns true if both operands are true
.books{.price > 19 && .author.name === "Robert C. Martin"}
||
returns true if one or both operands are true
.books{.title === "Maintainable JavaScript" || .title === "Clean Code"}
!
returns true if operand is false
.books{!.title}
In JSPATH, logical operators convert their operands to boolean values using the following rules:
  • if the operand is an array with length greater than 0, the result will be true, otherwise false
  • in all other cases, coercion is used via double negation in JavaScript (!!)

Arithmetic Operators

operator
description
+
addition
-
subtraction
*
multiplication
/
division
%
remainder

Operator Precedence

precedence
operator
1 (highest)
!, unary -
2
*, /, %
3
+, binary -
4
<, <=, >, >=
5
==, ===, !=, !==, ^=, ^==, $==, $=, *=, *==, =^, ==^, =$, ==$, =*, ==*
6
&&
7 (lowest)
||
Parentheses (( and )) are used to explicitly denote precedence by grouping parts of an expression that should be evaluated first.

Examples

// find all book titles where the author is Robert C. Martin
'.books{.author.name === "Robert C. Martin"}.title';
/* ['Clean Code', 'Agile Software Development'] */

// find all book titles with price less than 17
".books{.price < 17}.title";
/* ['Maintainable JavaScript', 'JavaScript: The Good Parts'] */
Positional Predicates
Positional predicates allow you to filter elements by their position in the context. All positional predicates are enclosed in square brackets ([ and ]).
JSPATH supports four types of positional predicates – also known as slice methods:
operator
description
example
[index]
returns the element in the context with index index – the first element has index 0, positional predicates are zero-based
[3] returns the fourth element in the context
[start:]
returns a range of elements whose index in the context is greater than or equal to start
[2:] returns elements whose index is greater than or equal to 2
[:end]
returns a range of elements whose index in the context is less than end
[:5] returns elements with indices from 0 to 4
[start:end]
returns a range of elements whose index in the context is greater than or equal to start and less than end
[2:5] returns elements with indices 2, 3, and 4
index, start, or end can be negative numbers, which means that JSPATH counts from the end rather than the beginning:
example
description
[-1]
returns the last element in the context
[-3:]
returns the last three elements in the context

Examples

Find the title of the first book
.books[0].title
Find the first title from books
.books.title[0]
Find the title of the last book
.books[-1].title
Find the titles of the first two books
.books[:2].title
Find the titles of the last two books
.books[-2:].title
Find the titles of two books starting from the second position
.books[1:3].title
Multiple Predicates
You can use more than one predicate – any combination of object and positional predicates. The result will contain only elements that match all predicates.

Examples

Find the title of the first book with price less than 15 and greater than 5
.books{.price < 15}{.price > 5}[0].title
Nested Predicates
You can nest predicates as deeply as you want – this eliminates the need to repeat deep nested paths each time, reducing query length. Similar to the "with" statement in JavaScript, all object properties become first-level properties inside a nested predicate.

Examples

Long nested paths: find books by various authors costing less than $20
.books{.price < 20 && (.author.name *== "Zakas" || .author.name *== "Martin")}.title
Nested predicates: same query, however ".author.name" is not repeated. For JSON with many levels, this allows for much more compact queries.
.books{.price < 20 && .author{.name *== "Zakas" || .name *== "Martin"}}.title

📌 Next step: Commands →
📌 Also useful: HTTP Requests | Flows