3 JSONPath functionality
Overview
JSONPath consists of segments separated with dots. A segment can be either a simple word like a JSON value name, or a more complex construct enclosed within square brackets [
]
. The separating dot before bracket segment is optional and can be omitted. For example:
See also: .
Supported segments
Segment | Description |
---|---|
<name> | Match object property by name. |
| Match all object properties. |
[‘<name>’] | Match object property by name. |
[‘<name>’, ‘<name>’, …] | Match object property by any of the listed names. |
[<index>] | Match array element by the index. |
[<number>, <number>, …] | Match array element by any of the listed indexes. |
[] | Match all object properties or array elements. |
[<start>:<end>] | Match array elements by the defined range: <start> - the first index to match (including). If not specified matches all array elements from the beginning. If negative specifies starting offset from the end of array. <end> - the last index to match (excluding). If not specified matches all array elements to the end. If negative specifies starting offset from the end of array. |
[?(<expression>)] | Match objects/array elements by applying filter expression. |
To find a matching segment ignoring its ancestry (detached segment) it must be prefixed with ‘..’ , for example $..name
or $..['name']
return values of all ‘name’ properties.
Matched element names can be extracted by adding a ~
suffix to the JSONPath. It returns the name of the matched object or an index in string format of the matched array item. The output format follows the same rules as other JSONPath queries - definite path results are returned ‘as is’ and indefinite path results are returned in array. However there is not much point of extracting the name of an element matching a definite path - it’s already known.
Filter expression
Supported operands:
Supported operators:
Operator | Type | Description | Result |
---|---|---|---|
- | binary | Subtraction. | Number. |
binary | Addition. | Number. | |
/ | binary | Division. | Number. |
* | binary | Multiplication. | Number. |
== | binary | Is equal to. | Boolean (1 or 0). |
!= | binary | Is not equal to. | Boolean (1 or 0). |
< | binary | Is less than. | Boolean (1 or 0). |
<= | binary | Is less than or equal to. | Boolean (1 or 0). |
> | binary | Is greater than. | Boolean (1 or 0). |
>= | binary | Is greater than or equal to. | Boolean (1 or 0). |
=~ | binary | Matches regular expression. | Boolean (1 or 0). |
! | unary | Boolean not. | Boolean (1 or 0). |
|| | binary | Boolean or. | Boolean (1 or 0). |
&& | binary | Boolean and. | Boolean (1 or 0). |
Functions
Functions can be used at the end of JSONPath. Multiple functions can be chained if the preceding function returns value that is accepted by the following function.
Supported functions:
Incompatible input will cause the function to generate error.
Output value
JSONPaths can be divided in definite and indefinite paths. A definite path can return only null or a single match. An indefinite path can return multiple matches, basically JSONPaths with detached, multiple name/index list, array slice or expression segments. However, when a function is used the JSONPath becomes definite, as functions always output single value.
A definite path returns the object/array/value it’s referencing, while indefinite path returns an array of the matched objects/arrays/values.
Whitespace
Whitespace (space, tab characters) can be freely used in bracket notation segments and expressions, for example, $[ 'a' ][ 0 ][ ?( $.b == 'c' ) ][ : -1 ].first( )
.
Strings
Examples
Input data
JSONPath | Type | Result | Comments |
---|---|---|---|
$.filters.price | definite | 10 | |
$.filters.category | definite | fiction | |
$.filters[‘no filters’] | definite | no “filters” | |
$.filters | definite | { “price”: 10, “category”: “fiction”, “no filters”: “no \”filters\”” } | |
$.books[1].title | definite | Sword of Honour | |
$.books[-1].author | definite | J. R. R. Tolkien | |
$.books.length() | definite | 4 | |
$.tags[:] | indefinite | [“a”, “b”, “c”, “d”, “e” ] | |
indefinite | [“c”, “d”, “e” ] | ||
$.tags[:3] | indefinite | [“a”, “b”, “c”] | |
$.tags[1:4] | indefinite | [“b”, “c”, “d”] | |
$.tags[-2:] | indefinite | [“d”, “e”] | |
$.tags[:-3] | indefinite | [“a”, “b”] | |
$.tags[:-3].length() | definite | 2 | |
$.books[0, 2].title | indefinite | [“Sayings of the Century”, “Moby Dick”] | |
$.books[1][‘author’, “title”] | indefinite | [“Evelyn Waugh”, “Sword of Honour”] | |
$..id | indefinite | [1, 2, 3, 4] | |
$.services..price | indefinite | [5, 154.99, 46, 24.5, 99.49] | |
$.books[?(@.id == 4 - 0.4 5)].title | indefinite | [“Sword of Honour”] | This query shows that arithmetical operations can be used in queries. Of course this query can be simplified to $.books[?(@.id == 2)].title |
$.books[?(@.id == 2 || @.id == 4)].title | indefinite | [“Sword of Honour”, “The Lord of the Rings”] | |
$.books[?(!(@.id == 2))].title | indefinite | [“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”] | |
$.books[?(@.id != 2)].title | indefinite | [“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”] | |
$.books[?(@.title =~ “ of “)].title | indefinite | [“Sayings of the Century”, “Sword of Honour”, “The Lord of the Rings”] | |
$.books[?(@.price > 12.99)].title | indefinite | [“The Lord of the Rings”] | |
$.books[?(@.author > “Herman Melville”)].title | indefinite | [“Sayings of the Century”, “The Lord of the Rings”] | |
$.books[?(@.price > $.filters.price)].title | indefinite | [“Sword of Honour”, “The Lord of the Rings”] | |
$.books[?(@.category == $.filters.category)].title | indefinite | [“Sword of Honour”,”Moby Dick”,”The Lord of the Rings”] | |
$..[?(@.id)] | indefinite | [ { “category”: “reference”, “author”: “Nigel Rees”, “title”: “Sayings of the Century”, “price”: 8.95, “id”: 1 }, { “category”: “fiction”, “author”: “Evelyn Waugh”, “title”: “Sword of Honour”, “price”: 12.99, “id”: 2 }, { “category”: “fiction”, “author”: “Herman Melville”, “title”: “Moby Dick”, “isbn”: “0-553-21311-3”, “price”: 8.99, “id”: 3 }, { “category”: “fiction”, “author”: “J. R. R. Tolkien”, “title”: “The Lord of the Rings”, “isbn”: “0-395-19395-8”, “price”: 22.99, “id”: 4 } ] | |
$.services..[?(@.price > 50)].description | indefinite | ‘[“Printing and assembling book in A5 format”, “Rebinding torn book”] | |
$..id.length() | definite | 4 | |
$.books[?(@.id == 2)].title.first() | definite | Sword of Honour | |
$..tags.first().length() | definite | 5 | $..tags is indefinite path, so it returns an array of matched elements - [[“a”, “b”, “c”, “d”, “e” ]], first() returns the first element - [“a”, “b”, “c”, “d”, “e” ] and finally length() calculates its length - 5. |
$.books[].price.min() | definite | 8.95 | |
$..price.max() | definite | 154.99 | |
$.books[?(@.category == “fiction”)].price.avg() | definite | 14.99 | |
$.books[?(@.category == $.filters.xyz)].title | indefinite | A query without match returns NULL for definite and indefinite paths. | |
$.services[?(@.active==”true”)].servicegroup | indefinite | [1000,1001] | Text constants must be used in boolean value comparisons. |
indefinite | [1002] | Text constants must be used in boolean value comparisons. | |
$.services[?(@.servicegroup==”1002”)]~.first() | definite | restoration |