< draft-ietf-jsonpath-base-04.txt   draft-ietf-jsonpath-base-05.txt >
JSONPath WG S. Gössner, Ed. JSONPath WG S. Gössner, Ed.
Internet-Draft Fachhochschule Dortmund Internet-Draft Fachhochschule Dortmund
Intended status: Standards Track G. Normington, Ed. Intended status: Standards Track G. Normington, Ed.
Expires: 8 September 2022 Expires: 27 October 2022
C. Bormann, Ed. C. Bormann, Ed.
Universität Bremen TZI Universität Bremen TZI
7 March 2022 25 April 2022
JSONPath: Query expressions for JSON JSONPath: Query expressions for JSON
draft-ietf-jsonpath-base-04 draft-ietf-jsonpath-base-05
Abstract Abstract
JSONPath defines a string syntax for selecting and extracting values JSONPath defines a string syntax for selecting and extracting values
within a JavaScript Object Notation (JSON, RFC 8259) value. within a JavaScript Object Notation (JSON, RFC 8259) value.
About This Document About This Document
This note is to be removed before publishing as an RFC. This note is to be removed before publishing as an RFC.
skipping to change at page 1, line 48 skipping to change at page 1, line 48
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on 8 September 2022. This Internet-Draft will expire on 27 October 2022.
Copyright Notice Copyright Notice
Copyright (c) 2022 IETF Trust and the persons identified as the Copyright (c) 2022 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/ Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document. license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights Please review these documents carefully, as they describe your rights
skipping to change at page 2, line 25 skipping to change at page 2, line 25
extracted from this document must include Revised BSD License text as extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License. provided without warranty as described in the Revised BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. History . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2. History . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3. Overview of JSONPath Expressions . . . . . . . . . . . . 5 1.3. Overview of JSONPath Expressions . . . . . . . . . . . . 5
2. JSONPath Examples . . . . . . . . . . . . . . . . . . . . . . 6 2. JSONPath Examples . . . . . . . . . . . . . . . . . . . . . . 7
3. JSONPath Syntax and Semantics . . . . . . . . . . . . . . . . 8 3. JSONPath Syntax and Semantics . . . . . . . . . . . . . . . . 9
3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 8 3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2. Processing Model . . . . . . . . . . . . . . . . . . . . 9 3.2. Processing Model . . . . . . . . . . . . . . . . . . . . 10
3.3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 10 3.3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4. Semantics . . . . . . . . . . . . . . . . . . . . . . . . 10 3.4. Semantics . . . . . . . . . . . . . . . . . . . . . . . . 11
3.5. Selectors . . . . . . . . . . . . . . . . . . . . . . . . 11 3.5. Selectors . . . . . . . . . . . . . . . . . . . . . . . . 12
3.5.1. Root Selector . . . . . . . . . . . . . . . . . . . . 12 3.5.1. Root Selector . . . . . . . . . . . . . . . . . . . . 13
3.5.2. Dot Selector . . . . . . . . . . . . . . . . . . . . 12 3.5.2. Dot Selector . . . . . . . . . . . . . . . . . . . . 14
3.5.3. Dot Wild Card Selector . . . . . . . . . . . . . . . 13 3.5.3. Dot Wildcard Selector . . . . . . . . . . . . . . . . 15
3.5.4. Index Selector . . . . . . . . . . . . . . . . . . . 13 3.5.4. Index Selector . . . . . . . . . . . . . . . . . . . 15
3.5.5. Index Wild Card Selector . . . . . . . . . . . . . . 16 3.5.5. Index Wildcard Selector . . . . . . . . . . . . . . . 19
3.5.6. Array Slice Selector . . . . . . . . . . . . . . . . 16 3.5.6. Array Slice Selector . . . . . . . . . . . . . . . . 20
3.5.7. Descendant Selector . . . . . . . . . . . . . . . . . 20 3.5.7. Descendant Selector . . . . . . . . . . . . . . . . . 25
3.5.8. List Selector . . . . . . . . . . . . . . . . . . . . 21 3.5.8. Filter Selector . . . . . . . . . . . . . . . . . . . 28
3.5.9. Filter Selector . . . . . . . . . . . . . . . . . . . 21 3.5.9. List Selector . . . . . . . . . . . . . . . . . . . . 31
3.6. Normalized Paths . . . . . . . . . . . . . . . . . . . . 25 3.6. Semantics of null . . . . . . . . . . . . . . . . . . . . 33
4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 3.7. Normalized Paths . . . . . . . . . . . . . . . . . . . . 34
4.1. Registration of Media Type application/jsonpath . . . . . 26 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 36
5. Security Considerations . . . . . . . . . . . . . . . . . . . 27 4.1. Registration of Media Type application/jsonpath . . . . . 36
6. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 5. Security Considerations . . . . . . . . . . . . . . . . . . . 37
6.1. Normative References . . . . . . . . . . . . . . . . . . 27 5.1. Attack vectors on JSONPath Implementations . . . . . . . 37
6.2. Informative References . . . . . . . . . . . . . . . . . 28 5.2. Attacks on Security Mechanisms that Employ JSONPath . . . 38
Appendix A. Inspired by XPath . . . . . . . . . . . . . . . . . 29 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 38
A.1. JSONPath and XPath . . . . . . . . . . . . . . . . . . . 30 6.1. Normative References . . . . . . . . . . . . . . . . . . 38
Appendix B. JSON Pointer . . . . . . . . . . . . . . . . . . . . 33 6.2. Informative References . . . . . . . . . . . . . . . . . 39
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 33 Appendix A. Inspired by XPath . . . . . . . . . . . . . . . . . 39
Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 33 A.1. JSONPath and XPath . . . . . . . . . . . . . . . . . . . 41
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 34
Appendix B. JSON Pointer . . . . . . . . . . . . . . . . . . . . 44
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 44
Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 45
1. Introduction 1. Introduction
JavaScript Object Notation (JSON, [RFC8259]) is a popular JavaScript Object Notation (JSON, [RFC8259]) is a popular
representation format for structured data values. JSONPath defines a representation format for structured data values. JSONPath defines a
string syntax for identifying values within a JSON value. string syntax for identifying values within a JSON value.
JSONPath is not intended as a replacement for, but as a more powerful JSONPath is not intended as a replacement for, but as a more powerful
companion to, JSON Pointer [RFC6901]. See Appendix B. companion to, JSON Pointer [RFC6901]. See Appendix B.
skipping to change at page 4, line 24 skipping to change at page 4, line 29
Argument: Short name for the value a JSONPath expression is applied Argument: Short name for the value a JSONPath expression is applied
to. to.
Node: The pair of a value along with its location within the Node: The pair of a value along with its location within the
argument. argument.
Root Node: The unique node whose value is the entire argument. Root Node: The unique node whose value is the entire argument.
Children (of a node): If the node is an array, each of its elements, Children (of a node): If the node is an array, each of its elements,
or if the node is an object, each its member values (but not its or if the node is an object, each its member values (but not its
member names). member names). If the node is neither an array nor an object, it
has no descendants.
Descendants (of a node): The node itself, plus the descendants of Descendants (of a node): The children of the node, together with the
each of its children. children of its children, and so forth recursively. More
// Note that this is often more selectively called descendant-or- formally, the descendants relation between nodes is the transitive
// self. Should we define descendants non-inclusive of the node closure of the children relation.
// itself? We do have the language to say "node + descendants" in
// several places.
Nodelist: A list of nodes. The output of applying a query to an Nodelist: A list of nodes. The output of applying a query to an
argument is manifested as a list of nodes. While this list can be argument is manifested as a list of nodes. While this list can be
represented in JSON, e.g. as an array, the nodelist is an abstract represented in JSON, e.g. as an array, the nodelist is an abstract
concept unrelated to JSON values. concept unrelated to JSON values.
Normalized Path: A simple form of JSONPath expression that Normalized Path: A simple form of JSONPath expression that
identifies a node by providing a query that results in exactly identifies a node by providing a query that results in exactly
that node. Similar to, but syntactically different from, a JSON that node. Similar to, but syntactically different from, a JSON
Pointer [RFC6901]. Pointer [RFC6901].
Singular Path: A JSONPath expression built from selectors which each
select at most one node.
For the purposes of this specification, a value as defined by For the purposes of this specification, a value as defined by
[RFC8259] is also viewed as a tree of nodes. Each node, in turn, [RFC8259] is also viewed as a tree of nodes. Each node, in turn,
holds a value. Further nodes within each value are the elements of holds a value. Further nodes within each value are the elements of
arrays and the member values of objects and are themselves values. arrays and the member values of objects and are themselves values.
(The type of the value held by a node may also be referred to as the (The type of the value held by a node may also be referred to as the
type of the node.) type of the node.)
A query is applied to an argument, and the output is a nodelist. A query is applied to an argument, and the output is a nodelist.
1.2. History 1.2. History
skipping to change at page 5, line 43 skipping to change at page 6, line 4
Within the JSONPath expression, the abstract name $ is used to refer Within the JSONPath expression, the abstract name $ is used to refer
to the _root node_ of the argument, i.e., to the argument as a whole. to the _root node_ of the argument, i.e., to the argument as a whole.
JSONPath expressions can use the _dot notation_ JSONPath expressions can use the _dot notation_
$.store.book[0].title $.store.book[0].title
or the more general _bracket notation_ or the more general _bracket notation_
$['store']['book'][0]['title'] $['store']['book'][0]['title']
to build paths that are input to a JSONPath implementation. to build paths that are input to a JSONPath implementation.
JSONPath allows the wildcard symbol * to select any member of an JSONPath allows the wildcard symbol * to select any member of an
object or any element of an array (Section 3.5.3). The descendant object or any element of an array (Section 3.5.3). The descendant
operator .. selects the node and all its descendants (Section 3.5.7). operator .. selects all the descendants (Section 3.5.7) of a node.
The array slice syntax [start:end:step] allows selecting a regular The array slice syntax [start:end:step] allows selecting a regular
selection of an element from an array, giving a start position, an selection of an element from an array, giving a start position, an
end position, and possibly a step value that moves the position from end position, and possibly a step value that moves the position from
the start to the end (Section 3.5.6). the start to the end (Section 3.5.6).
Filter expressions are supported via the syntax ?(<boolean expr>) as Filter expressions are supported via the syntax ?(<boolean expr>) as
in in
$.store.book[?(@.price < 10)].title $.store.book[?(@.price < 10)].title
Table 1 provides a quick overview of the JSONPath syntax elements. Table 1 provides a quick overview of the JSONPath syntax elements.
+==================+============================================+ +===========+=============================================+
| JSONPath | Description | | JSONPath | Description |
+==================+============================================+ +===========+=============================================+
| $ | the root node | | $ | the root node (Section 3.5.1) |
+------------------+--------------------------------------------+ +-----------+---------------------------------------------+
| @ | the current node | | @ | the current node: within filter selectors |
+------------------+--------------------------------------------+ | | (Section 3.5.8) |
| . or [] | child operator | +-----------+---------------------------------------------+
+------------------+--------------------------------------------+ | .name | child selectors for JSON objects: dot |
| n/a | parent operator | | | selector (Section 3.5.2) |
+------------------+--------------------------------------------+ +-----------+---------------------------------------------+
| .. | nested descendants | | ['name'] | child selectors for JSON objects: index |
+------------------+--------------------------------------------+ | | selector (Section 3.5.4) |
| * | wildcard: all member values/array elements | +-----------+---------------------------------------------+
| | regardless of their names/indices | | .. | descendants: descendant selector |
+------------------+--------------------------------------------+ | | (Section 3.5.7) |
| [] | subscript operator: index current node as | +-----------+---------------------------------------------+
| | an array (from 0) | | * | all child member values and array elements: |
+------------------+--------------------------------------------+ | | dot wildcard selector (Section 3.5.3), |
| [,] | list operator: allows combining member | | | index wildcard selector (Section 3.5.5) |
| | names, array indices, and slices | +-----------+---------------------------------------------+
+------------------+--------------------------------------------+ | [3] | index (subscript) selector (Section 3.5.4): |
| [start:end:step] | array slice operator | | | index current node as an array (from 0) |
+------------------+--------------------------------------------+ +-----------+---------------------------------------------+
| ?() | applies a filter expression | | [..,..] | list selector (Section 3.5.9): allow |
+------------------+--------------------------------------------+ | | combining selector styles |
| () | expression, e.g., for indexing | +-----------+---------------------------------------------+
+------------------+--------------------------------------------+ | [0:100:5] | array slice selector (Section 3.5.6): |
| | start:end:step |
+-----------+---------------------------------------------+
| ?... | filter selector (Section 3.5.8) |
+-----------+---------------------------------------------+
| () | expression: within filter selectors |
| | (Section 3.5.8) |
+-----------+---------------------------------------------+
Table 1: Overview over JSONPath Table 1: Overview of JSONPath
2. JSONPath Examples 2. JSONPath Examples
This section provides some more examples for JSONPath expressions. This section provides some more examples for JSONPath expressions.
The examples are based on the simple JSON value shown in Figure 1, The examples are based on the simple JSON value shown in Figure 1,
which was patterned after a typical XML example representing a which was patterned after a typical XML example representing a
bookstore (that also has bicycles). bookstore (that also has bicycles).
{ "store": { { "store": {
"book": [ "book": [
skipping to change at page 10, line 35 skipping to change at page 11, line 35
3.3. Syntax 3.3. Syntax
Syntactically, a JSONPath query consists of a root selector ($), Syntactically, a JSONPath query consists of a root selector ($),
which stands for a nodelist that contains the root node of the which stands for a nodelist that contains the root node of the
argument, followed by a possibly empty sequence of _selectors_. argument, followed by a possibly empty sequence of _selectors_.
json-path = root-selector *(S (dot-selector / json-path = root-selector *(S (dot-selector /
dot-wild-selector / dot-wild-selector /
index-selector / index-selector /
index-wild-selector / index-wild-selector /
list-selector /
slice-selector / slice-selector /
descendant-selector / descendant-selector /
filter-selector)) filter-selector /
list-selector))
The syntax and semantics of each selector is defined below. The syntax and semantics of each selector is defined below.
3.4. Semantics 3.4. Semantics
The root selector $ not only selects the root node of the argument, The root selector $ not only selects the root node of the argument,
but it also produces as output a list consisting of one node: the but it also produces as output a list consisting of one node: the
argument itself. argument itself.
A selector may select zero or more nodes for further processing. A A selector may select zero or more nodes for further processing. A
skipping to change at page 11, line 52 skipping to change at page 12, line 52
3.5. Selectors 3.5. Selectors
A JSONPath query consists of a sequence of selectors. Valid A JSONPath query consists of a sequence of selectors. Valid
selectors are selectors are
* Root selector $ (used at the start of a query and in expressions) * Root selector $ (used at the start of a query and in expressions)
* Dot selector .<name>, used with object member names exclusively. * Dot selector .<name>, used with object member names exclusively.
* Dot wild card selector .*. * Dot wildcard selector .*.
* Index selector [<index>], where <index> is either a (possibly * Index selector [<index>], where <index> is either a (possibly
negative, see Section "Semantics") array index or an object member negative, see Section "Semantics") array index or an object member
name. name.
* Index wild card selector [*]. * Index wildcard selector [*].
* Array slice selector [<start>:<end>:<step>], where the optional * Array slice selector [<start>:<end>:<step>], where the optional
values <start>, <end>, and <step> are integer literals. values <start>, <end>, and <step> are integer literals.
* Nested descendants selector ... * Descendants selector ...
* List selector [<sel1>,<sel2>,...,<selN>], holding a comma * List selector [<sel1>,<sel2>,...,<selN>], holding a comma
separated list of index and slice selectors. separated list of index and slice selectors.
* Filter selector [?(<expr>)] * Filter selector [?(<expr>)]
* Current item selector @ (used in expressions) * Current item selector @ (used in expressions)
3.5.1. Root Selector 3.5.1. Root Selector
skipping to change at page 12, line 36 skipping to change at page 13, line 36
Every valid JSONPath query MUST begin with the root selector $. Every valid JSONPath query MUST begin with the root selector $.
root-selector = "$" root-selector = "$"
Semantics Semantics
The Argument -- the root JSON value -- becomes the root node, which The Argument -- the root JSON value -- becomes the root node, which
is addressed by the root selector $. is addressed by the root selector $.
Examples
JSON document:
{"k": "v"}
Queries:
+=======+============+=============+===========+
| Query | Result | Result Path | Comment |
+=======+============+=============+===========+
| $ | {"k": "v"} | $ | Root node |
+-------+------------+-------------+-----------+
Table 3: Root selector examples
3.5.2. Dot Selector 3.5.2. Dot Selector
Syntax Syntax
A dot selector starts with a dot . followed by an object's member A dot selector starts with a dot . followed by an object's member
name. name.
dot-selector = "." dot-member-name dot-selector = "." dot-member-name
dot-member-name = name-first *name-char dot-member-name = name-first *name-char
name-first = name-first =
skipping to change at page 13, line 4 skipping to change at page 14, line 22
dot-selector = "." dot-member-name dot-selector = "." dot-member-name
dot-member-name = name-first *name-char dot-member-name = name-first *name-char
name-first = name-first =
ALPHA / ALPHA /
"_" / ; _ "_" / ; _
%x80-10FFFF ; any non-ASCII Unicode character %x80-10FFFF ; any non-ASCII Unicode character
name-char = DIGIT / name-first name-char = DIGIT / name-first
DIGIT = %x30-39 ; 0-9 DIGIT = %x30-39 ; 0-9
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
Member names containing characters other than allowed by dot-selector Member names containing characters other than allowed by dot-selector
-- such as space ` , minus-, or dot.characters -- MUST NOT be used -- such as space ` , minus-, or dot.characters -- MUST NOT be used
with thedot-selector. (Such member names can be addressed by with thedot-selector. (Such member names can be addressed by
theindex-selector` instead.) theindex-selector` instead.)
Semantics Semantics
The dot-selector selects the node of the member value corresponding The dot-selector selects the node of the member value corresponding
to the member name from any JSON object in its input nodelist. It to the member name from any JSON object in its input nodelist. It
selects no nodes from any other JSON value. selects no nodes from any other JSON value.
3.5.3. Dot Wild Card Selector Examples
JSON document:
{"j": {"k": 3}}
Queries:
+=======+==========+==============+==============================+
| Query | Result | Result Paths | Comment |
+=======+==========+==============+==============================+
| $.j | {"k": 3} | $['j'] | Named value of an object |
+-------+----------+--------------+------------------------------+
| $.j.k | 3 | $['j']['k'] | Named value in nested object |
+-------+----------+--------------+------------------------------+
Table 4: Dot selector examples
3.5.3. Dot Wildcard Selector
Syntax Syntax
The dot wild card selector has the form .* as defined in the The dot wildcard selector has the form .* as defined in the following
following syntax: syntax:
dot-wild-selector = "." "*" ; dot followed by asterisk dot-wild-selector = "." "*" ; dot followed by asterisk
Semantics Semantics
A dot-wild-selector acts as a wild card by selecting the nodes of all A dot-wild-selector acts as a wildcard by selecting the nodes of all
member values of an object in its input nodelist as well as all member values of an object in its input nodelist as well as all
element nodes of an array in its input nodelist. Applying the dot- element nodes of an array in its input nodelist. Applying the dot-
wild-selector to a primitive JSON value (number, string, or wild-selector to a primitive JSON value (number, string, or
true/false/null) selects no node. true/false/null) selects no node.
3.5.4. Index Selector Examples
JSON document:
{
"o": {"j": 1, "k": 2},
"a": [5, 3]
}
Queries:
+=======+========+==============+=============+
| Query | Result | Result Paths | Comment |
+=======+========+==============+=============+
| $.o.* | 1 | $['o']['j'] | Object |
| | 2 | $['o']['k'] | values |
+-------+--------+--------------+-------------+
| $.o.* | 2 | $['o']['k'] | Alternative |
| | 1 | $['o']['j'] | result |
+-------+--------+--------------+-------------+
| $.a.* | 5 | $['a'][0] | Array |
| | 3 | $['a'][1] | members |
+-------+--------+--------------+-------------+
Table 5: Dot wildcard selector examples
3.5.4. Index Selector
Syntax Syntax
An index selector [<index>] addresses at most one object member value An index selector [<index>] addresses at most one object member value
or at most one array element value. or at most one array element value.
index-selector = "[" S (quoted-member-name / element-index) S "]" index-selector = "[" S (quoted-member-name / element-index) S "]"
Applying the index-selector to an object value in its input nodelist, Applying the index-selector to an object value in its input nodelist,
a quoted-member-name string is required to select the corresponding a quoted-member-name string is required to select the corresponding
member value. In contrast to JSON, the JSONPath syntax allows member value. In contrast to JSON, the JSONPath syntax allows
skipping to change at page 15, line 47 skipping to change at page 18, line 47
| \' | U+0027 | apostrophe | | \' | U+0027 | apostrophe |
+-----------------+-------------------+-----------------------------+ +-----------------+-------------------+-----------------------------+
| \/ | U+002F | slash (solidus) | | \/ | U+002F | slash (solidus) |
+-----------------+-------------------+-----------------------------+ +-----------------+-------------------+-----------------------------+
| \\ | U+005C | backslash (reverse | | \\ | U+005C | backslash (reverse |
| | | solidus) | | | | solidus) |
+-----------------+-------------------+-----------------------------+ +-----------------+-------------------+-----------------------------+
| \uXXXX | U+XXXX | unicode character | | \uXXXX | U+XXXX | unicode character |
+-----------------+-------------------+-----------------------------+ +-----------------+-------------------+-----------------------------+
Table 3: Escape Sequence Replacements Table 6: Escape Sequence Replacements
The index-selector applied with a quoted-member-name to an object The index-selector applied with a quoted-member-name to an object
selects the node of the corresponding member value from it, if and selects the node of the corresponding member value from it, if and
only if that object has a member with that name. Nothing is selected only if that object has a member with that name. Nothing is selected
from a value that is not a object. from a value that is not a object.
Array indexing via element-index is a way of selecting a particular Array indexing via element-index is a way of selecting a particular
array element using a zero-based index. For example, selector [0] array element using a zero-based index. For example, selector [0]
selects the first and selector [4] the fifth element of a selects the first and selector [4] the fifth element of a
sufficiently long array. sufficiently long array.
A negative element-index counts from the array end. For example, A negative element-index counts from the array end. For example,
selector [-1] selects the last and selector [-2] selects the selector [-1] selects the last and selector [-2] selects the
penultimate element of an array with at least two elements. As with penultimate element of an array with at least two elements. As with
non-negative indexes, it is not an error if such an element does not non-negative indexes, it is not an error if such an element does not
exist; this simply means that no element is selected. exist; this simply means that no element is selected.
3.5.5. Index Wild Card Selector Examples
JSON document:
{
"o": {"j j": {"k.k": 3}},
"a": ["a","b"]
}
Queries:
+===================+========+==============+==================+
| Query | Result | Result Paths | Comment |
+===================+========+==============+==================+
| $.o['j j']['k.k'] | 3 | $['o']['j | Named value in |
| | | ']['k.k'] | nested object |
+-------------------+--------+--------------+------------------+
| $.o["j j"]["k.k"] | 3 | $['o']['j | Named value in |
| | | ']['k.k'] | nested object |
+-------------------+--------+--------------+------------------+
| $.a[1] | "b" | $['a'][1] | Member of array |
+-------------------+--------+--------------+------------------+
| $.a[-2] | "a" | $['a'][0] | Member of array, |
| | | | from the end |
+-------------------+--------+--------------+------------------+
Table 7: Index selector examples
3.5.5. Index Wildcard Selector
Syntax Syntax
The index wild card selector has the form [*]. The index wildcard selector has the form [*].
index-wild-selector = "[" "*" "]" ; asterisk enclosed by brackets index-wild-selector = "[" "*" "]" ; asterisk enclosed by brackets
Semantics Semantics
An index-wild-selector selects the nodes of all member values of an An index-wild-selector selects the nodes of all member values of an
object as well as of all elements of an array. Applying the index- object as well as of all elements of an array. Applying the index-
wild-selector to a primitive JSON value (such as a number, string, or wild-selector to a primitive JSON value (such as a number, string, or
true/false/null) selects no node. true/false/null) selects no node.
The index-wild-selector behaves identically to the dot-wild-selector. The index-wild-selector behaves identically to the dot-wild-selector.
Examples
JSON document:
{
"o": {"j": 1, "k": 2},
"a": [5, 3]
}
Queries:
+=========+========+==============+=============+
| Query | Result | Result Paths | Comment |
+=========+========+==============+=============+
| $.o.[*] | 1 | $['o']['j'] | Object |
| | 2 | $['o']['k'] | values |
+---------+--------+--------------+-------------+
| $.o.[*] | 2 | $['o']['k'] | Alternative |
| | 1 | $['o']['j'] | result |
+---------+--------+--------------+-------------+
| $.a.[*] | 5 | $['a'][0] | Array |
| | 3 | $['a'][1] | members |
+---------+--------+--------------+-------------+
Table 8: Index wildcard selector examples
3.5.6. Array Slice Selector 3.5.6. Array Slice Selector
Syntax Syntax
The array slice selector has the form [<start>:<end>:<step>]. It The array slice selector has the form [<start>:<end>:<step>]. It
selects elements starting at index <start>, ending at -- but not selects elements starting at index <start>, ending at -- but not
including -- <end>, while incrementing by step. including -- <end>, while incrementing by step.
slice-selector = "[" S slice-index S "]" slice-selector = "[" S slice-index S "]"
skipping to change at page 18, line 42 skipping to change at page 22, line 42
end depend on the sign of step, as follows: end depend on the sign of step, as follows:
+===========+=========+==========+ +===========+=========+==========+
| Condition | start | end | | Condition | start | end |
+===========+=========+==========+ +===========+=========+==========+
| step >= 0 | 0 | len | | step >= 0 | 0 | len |
+-----------+---------+----------+ +-----------+---------+----------+
| step < 0 | len - 1 | -len - 1 | | step < 0 | len - 1 | -len - 1 |
+-----------+---------+----------+ +-----------+---------+----------+
Table 4: Default array slice Table 9: Default array slice
start and end values start and end values
Slice expression parameters start and end are not directly usable as Slice expression parameters start and end are not directly usable as
slice bounds and must first be normalized. Normalization for this slice bounds and must first be normalized. Normalization for this
purpose is defined as: purpose is defined as:
FUNCTION Normalize(i, len): FUNCTION Normalize(i, len):
IF i >= 0 THEN IF i >= 0 THEN
RETURN i RETURN i
ELSE ELSE
skipping to change at page 20, line 29 skipping to change at page 24, line 29
END WHILE END WHILE
END IF END IF
When step = 0, no elements are selected and the result array is When step = 0, no elements are selected and the result array is
empty. empty.
To be valid, the slice expression parameters MUST be in the I-JSON To be valid, the slice expression parameters MUST be in the I-JSON
range of exact values, see Section 3.1. range of exact values, see Section 3.1.
Examples
JSON document:
["a", "b", "c", "d", "e", "f", "g"]
Queries:
+===========+========+========+==========+
| Query | Result | Result | Comment |
| | | Paths | |
+===========+========+========+==========+
| $[1:3] | "b" | $[1] | Slice |
| | "c" | $[2] | with |
| | | | default |
| | | | step |
+-----------+--------+--------+----------+
| $[1:5:2] | "b" | $[1] | Slice |
| | "d" | $[3] | with |
| | | | step 2 |
+-----------+--------+--------+----------+
| $[5:1:-2] | "f" | $[5] | Slice |
| | "d" | $[3] | with |
| | | | negative |
| | | | step |
+-----------+--------+--------+----------+
| $[::-1] | "g" | $[6] | Slice in |
| | "f" | $[5] | reverse |
| | "e" | $[4] | order |
| | "d" | $[3] | |
| | "c" | $[2] | |
| | "b" | $[1] | |
| | "a" | $[0] | |
+-----------+--------+--------+----------+
Table 10: Array slice selector examples
3.5.7. Descendant Selector 3.5.7. Descendant Selector
Syntax Syntax
The descendant selector starts with a double dot .. and can be The descendant selector starts with a double dot .. and can be
followed by an object member name (similar to the dot-selector), by followed by an object member name (similar to the dot-selector), by
an index-selector acting on objects or arrays, or by a wild card. an index-selector acting on objects or arrays, or by a wildcard.
descendant-selector = ".." ( dot-member-name / ; ..<name> descendant-selector = ".." ( dot-member-name / ; ..<name>
index-selector / ; ..[<index>] index-selector / ; ..[<index>]
index-wild-selector / ; ..[*] index-wild-selector / ; ..[*]
"*" ; ..* "*" ; ..*
) )
Semantics Semantics
The descendant-selector selects the node and all its descendants. The descendant-selector selects certain descendants of a node:
In the resultant nodelist: * nodes occur before their children, and * * the ..<name> form (and the ..[<index>] form where <index> is a
nodes of an array occur in array order. quoted-member-name) selects those descendants of the node that are
member values of an object with the given member name.
* the ..[<index>] where <index> is an element-index selects those
descendants of the node that are array elements with the given
index.
* the ..[*] and ..* forms select all the descendants of the node.
In the resultant nodelist:
* nodes occur before their children, and
* nodes of an array occur in array order.
Children of an object may occur in any order, since JSON objects are Children of an object may occur in any order, since JSON objects are
unordered. unordered.
3.5.8. List Selector Examples
The list selector allows combining member names, array indices, and JSON document:
slices in a single selector.
Note: The list selector was called "union selector" in {
[JSONPath-orig], as it was intended to solve use cases addressed by "o": {"j": 1, "k": 2},
the union selector in XPath. However, the term "union" has the "a": [5, 3, [{"j": 4}]]
connotation of a set operation that involves merging input sets while }
avoiding duplicates, so the concept was renamed into "list selector".
Syntax Queries:
The list selector is syntactically related to the index-selector and +========+====================+===================+=============+
the slice-selector. It contains two or more entries, separated by | Query | Result | Result Paths | Comment |
commas. +========+====================+===================+=============+
| $..j | 1 | $['o']['j'] | Object |
| | 4 | $['a'][2][0]['j'] | values |
+--------+--------------------+-------------------+-------------+
| $..j | 4 | $['a'][2][0]['j'] | Alternative |
| | 1 | $['o']['j'] | result |
+--------+--------------------+-------------------+-------------+
| $..[0] | 5 | $['a'][0] | Array |
| | {"j": 4} | $['a'][2][0] | values |
+--------+--------------------+-------------------+-------------+
| $..[0] | {"j": 4} | $['a'][2][0] | Alternative |
| | 5 | $['a'][0] | result |
+--------+--------------------+-------------------+-------------+
| $..[*] | {"j": 1, "k" : 2} | $['o'] | All values |
| | [5, 3, [{"j": 4}]] | $['a'] | |
| | 1 | $['o']['j'] | |
| | 2 | $['o']['k'] | |
| | 5 | $['a'][0] | |
| | 3 | $['a'][1] | |
| | [{"j": 4}] | $['a'][2] | |
| | {"j": 4} | $['a'][2][0] | |
| | 4 | $['a'][2][0]['j'] | |
+--------+--------------------+-------------------+-------------+
| $..* | [5, 3, [{"j": 4}]] | $['a'] | All values |
| | {"j": 1, "k" : 2} | $['o'] | |
| | 2 | $['o']['k'] | |
| | 1 | $['o']['j'] | |
| | 5 | $['a'][0] | |
| | 3 | $['a'][1] | |
| | [{"j": 4}] | $['a'][2] | |
| | {"j": 4} | $['a'][2][0] | |
| | 4 | $['a'][2][0]['j'] | |
+--------+--------------------+-------------------+-------------+
list-selector = "[" S list-entry 1*(S "," S list-entry) S "]" Table 11: Descendant selector examples
list-entry = ( quoted-member-name / Note: The ordering of the results for the $..[*] and $..* examples
element-index / above is not guaranteed, except that:
slice-index
)
Semantics * {"j": 1, "k": 2} must appear before 1 and 2,
A list selector selects the nodes that are selected by at least one * [5, 3, [{"j": 4}]] must appear before 5, 3, and [{"j": 4}],
of the selector entries in the list and yields the concatenation of
the lists (in the order of the selector entries) of nodes selected by
the selector entries. Note that any node selected in more than one
of the selector entries is kept as many times in the node list.
To be valid, integer values in the element-index and slice-index * 5 must appear before 3 which must appear before [{"j": 4}],
components MUST be in the I-JSON range of exact values, see
Section 3.1.
3.5.9. Filter Selector * [{"j": 4}] must appear before {"j": 4}, and
* {"j": 4} must appear before 4.
3.5.8. Filter Selector
Syntax Syntax
The filter selector has the form [?<expr>]. It works via iterating The filter selector has the form [?<expr>]. It works via iterating
over structured values, i.e. arrays and objects. over structured values, i.e. arrays and objects.
filter-selector = "[" S "?" S boolean-expr S "]" filter-selector = "[" S filter S "]"
filter = "?" S boolean-expr
During iteration process each array element or object member is During iteration process each array element or object member is
visited and its value -- accessible via symbol @ -- or one of its visited and its value -- accessible via symbol @ -- or one of its
descendants -- uniquely defined by a relative path -- is tested descendants -- uniquely defined by a relative path -- is tested
against a boolean expression boolean-expr. against a boolean expression boolean-expr.
The current item is selected if and only if the result is true. The current item is selected if and only if the result is true.
boolean-expr = logical-or-expr boolean-expr = logical-or-expr
logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) logical-or-expr = logical-and-expr *(S "||" S logical-and-expr)
; disjunction ; disjunction
; binds less tightly than conjunction ; binds less tightly than conjunction
logical-and-expr = basic-expr *(S "&&" S basic-expr) ; conjunction logical-and-expr = basic-expr *(S "&&" S basic-expr) ; conjunction
; binds more tightly than disjunction ; binds more tightly than disjunction
basic-expr = exist-expr / basic-expr = exist-expr /
paren-expr / paren-expr /
relation-expr relation-expr
exist-expr = [neg-op S] path ; path existence or non-existence exist-expr = [neg-op S] singular-path ; path existence or non-existence
path = rel-path / json-path
rel-path = "@" *(S (dot-selector / index-selector)) Paths in filter expressions are Singular Paths, each of which selects
paren-expr = [neg-op S] "(" S boolean-expr S ")" ; parenthesized expression at most one node.
neg-op = "!" ; not operator
singular-path = rel-singular-path / abs-singular-path
rel-singular-path = "@" *(S (dot-selector / index-selector))
abs-singular-path = root-selector *(S (dot-selector / index-selector))
Parentheses can be used with boolean-expr for grouping. So filter
selection syntax in the original proposal [?(<expr>)] is naturally
contained in the current lean syntax [?<expr>] as a special case.
paren-expr = [neg-op S] "(" S boolean-expr S ")" ; parenthesized expression
neg-op = "!" ; not operator
relation-expr = comp-expr / ; comparison test relation-expr = comp-expr / ; comparison test
regex-expr ; regular expression test regex-expr ; regular expression test
Comparisons are restricted to Singular Path values and primitive
values (such as number, string, true, false, null).
Comparisons with complex values will fail, i.e. no selection occurs.
Data types are not implicitly converted in comparisons. So "13 ==
'13'" selects no node.
A member or element value by itself in a Boolean context is
interpreted as false only if it does not exist. Otherwise it is
interpreted as true. To be more specific about the actual value,
explicit comparisons are necessary. This existence test -- as an
exception to the general rule -- also works with structured values.
comp-expr = comparable S comp-op S comparable comp-expr = comparable S comp-op S comparable
comparable = number / string-literal / ; primitive ... comparable = number / string-literal / ; primitive ...
true / false / null / ; values only true / false / null / ; values only
path ; path value singular-path ; Singular Path value
comp-op = "==" / "!=" / ; comparison ... comp-op = "==" / "!=" / ; comparison ...
"<" / ">" / ; operators "<" / ">" / ; operators
"<=" / ">=" "<=" / ">="
Alphabetic characters in ABNF are case-insensitive, so "e" can be
either "e" or "E".
true, false, and null are lower-case only (case-sensitive).
number = int [ frac ] [ exp ] ; decimal number number = int [ frac ] [ exp ] ; decimal number
frac = "." 1*DIGIT ; decimal fraction frac = "." 1*DIGIT ; decimal fraction
exp = "e" [ "-" / "+" ] 1*DIGIT ; decimal exponent exp = "e" [ "-" / "+" ] 1*DIGIT ; decimal exponent
true = %x74.72.75.65 ; true true = %x74.72.75.65 ; true
false = %x66.61.6c.73.65 ; false false = %x66.61.6c.73.65 ; false
null = %x6e.75.6c.6c ; null null = %x6e.75.6c.6c ; null
regex-expr = (path / string-literal) S regex-op S regex Regular expression tests can be applied to JSON string values
regex-op = "=~" ; regular expression match (Section 7 of [RFC8259]) only (on the left-hand side of =~); they
regex = string-literal ; I-Regexp yield false otherwise.
Notes:
* Parentheses can be used with boolean-expr for grouping. So filter
selection syntax in the original proposal [?(<expr>)] is naturally
contained in the current lean syntax [?<expr>] as a special case.
* Comparisons are restricted to primitive values (such as number,
string, true, false, null). Comparisons with complex values will
fail, i.e. no selection occurs.
* Data types are not implicitly converted in comparisons. So "13 ==
'13'" selects no node.
* A member or element value by itself in a Boolean context is
interpreted as false only if it does not exist. Otherwise it is
interpreted as true. To be more specific about the actual value,
explicit comparisons are necessary. This existence test -- as an
exception to the general rule -- also works with structured
values.
* The regular expressions in the string-literals on the right-hand
side of =~ are as defined in [I-D.draft-bormann-jsonpath-iregexp].
Regular expression tests can be applied to JSON string values
(Section 7 of [RFC8259]) only (on the left-hand side of =~); they
yield false otherwise.
* Alphabetic characters in ABNF are case-insensitive, so "e" can be
either "e" or "E".
* false, null, true are lower-case only (case-sensitive). The syntax of regular expressions in the string-literals on the
right-hand side of =~ is as defined in
[I-D.draft-bormann-jsonpath-iregexp].
regex-expr = (singular-path / string-literal) S regex-op S regex
regex-op = "=~" ; regular expression match
regex = string-literal ; I-Regexp
The following table lists filter expression operators in order of The following table lists filter expression operators in order of
precedence from highest (binds most tightly) to lowest (binds least precedence from highest (binds most tightly) to lowest (binds least
tightly). tightly).
+============+===========+===========+ +============+===========+===========+
| Precedence | Operator | Syntax | | Precedence | Operator | Syntax |
| | type | | | | type | |
+============+===========+===========+ +============+===========+===========+
| 5 | Grouping | (...) | | 5 | Grouping | (...) |
+------------+-----------+-----------+ +------------+-----------+-----------+
| 4 | Logical | ! | | 4 | Logical | ! |
| | NOT | | | | NOT | |
+------------+-----------+-----------+ +------------+-----------+-----------+
| 3 | Relations | == != | | 3 | Relations | == != |
| | | < <= > >= | | | | < <= > >= |
| | | =~ | | | | =~ |
| | | in |
+------------+-----------+-----------+ +------------+-----------+-----------+
| 2 | Logical | && | | 2 | Logical | && |
| | AND | | | | AND | |
+------------+-----------+-----------+ +------------+-----------+-----------+
| 1 | Logical | || | | 1 | Logical | || |
| | OR | | | | OR | |
+------------+-----------+-----------+ +------------+-----------+-----------+
Table 5: Filter expression Table 12: Filter expression
operator precedence operator precedence
Semantics Semantics
The filter-selector works with arrays and objects exclusively. Its The filter-selector works with arrays and objects exclusively. Its
result might be a list of _zero_, _one_, _multiple_ or _all_ of their result is a list of _zero_, _one_, _multiple_ or _all_ of their array
element or member values then. Applied to other value types, it will elements or member values, respectively. Applied to other value
select nothing. types, it will select nothing.
Some examples: A relative path, beginning with @, refers to the current array
element or member value as the filter selector iterates over the
array or object.
+===================+=====================+===============+=========+ Comparisons using one of the operators <, <=, >, and >= are between
|JSON | Query | Result |Comment | numeric values only. Using these operators to compare other types of
+===================+=====================+===============+=========+ values produces a "false" comparison result.
|{"a":1,"b":2} | $[?@] | [1,2] |Same as |
|[2,3,4] | | [2,3,4] |$.* or |
| | | |$[*] |
+-------------------+---------------------+---------------+---------+
|./. | $[?@==2] | [2] |Select by|
| | | [2] |value. |
+-------------------+---------------------+---------------+---------+
|{"a":{"b":{"c":{}}}| $[?@.b] |[{"b":{"c":{}}]|Existence|
| | $[?@.b.c] | | |
+-------------------+---------------------+---------------+---------+
|{"key":false} | $[?index(@)=='key'] | [false] |Select |
| | $[?index(@)==0] | [] |object |
| | | |member |
+-------------------+---------------------+---------------+---------+
|[3,4,5] | $[?index(@)==2] | [5] |Select |
| | $[?index(@)==17] | [] |array |
| | | |element |
+-------------------+---------------------+---------------+---------+
|{"a":{"b":{5},c:0}}| $[?@.b==5 && !@.c] |[{"b":{5},c:0}]|Existence|
+-------------------+---------------------+---------------+---------+
Table 6 The semantics of regular expressions are as defined in
[I-D.draft-bormann-jsonpath-iregexp].
3.6. Normalized Paths Examples
JSON document:
{
"a": [3, 5, 1, 2, 4, 6, {"b": "ij"}, {"b": "ik"}],
"o": {"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}}
}
Queries:
+=============+=============+=============+=============+
| Query | Result | Result | Comment |
| | | Paths | |
+=============+=============+=============+=============+
| $.a[?@>3.5] | 5 | $['a'][1] | Array value |
| | 4 | $['a'][4] | comparison |
| | 6 | $['a'][5] | |
+-------------+-------------+-------------+-------------+
| $.a[?@.b] | {"b": "ij"} | $['a'][6] | Array value |
| | {"b": "ik"} | $['a'][7] | existence |
+-------------+-------------+-------------+-------------+
| $.a[?@<2 || | 1 | $['a'][2] | Array value |
| @.b == | {"b": "ik"} | $['a'][7] | logical OR |
| "ik"] | | | |
+-------------+-------------+-------------+-------------+
| $.a[?@.b =~ | {"b": "ij"} | $['a'][6] | Array value |
| "i.*"] | {"b": "ik"} | $['a'][7] | regular |
| | | | expression |
+-------------+-------------+-------------+-------------+
| $.o[?@>1 && | 2 | $['o']['q'] | Object |
| @<4] | 3 | $['o']['r'] | value |
| | | | logical AND |
+-------------+-------------+-------------+-------------+
| $.o[?@>1 && | 3 | $['o']['r'] | Alternative |
| @<4] | 2 | $['o']['q'] | result |
+-------------+-------------+-------------+-------------+
| $.o[?@.u || | {"u": 6} | $['o']['t'] | Object |
| @.x] | | | value |
| | | | logical OR |
+-------------+-------------+-------------+-------------+
Table 13: Filter selector examples
3.5.9. List Selector
The list selector allows combining member names, array indices, and
slices in a single selector.
Note: The list selector was called "union selector" in
[JSONPath-orig], as it was intended to solve use cases addressed by
the union selector in XPath. However, the term "union" has the
connotation of a set operation that involves merging input sets while
avoiding duplicates, so the concept was renamed into "list selector".
Syntax
The list selector is syntactically related to the index-selector and
the slice-selector. It contains two or more entries, separated by
commas.
list-selector = "[" S list-entry 1*(S "," S list-entry) S "]"
list-entry = ( quoted-member-name /
element-index /
slice-index /
filter
)
Semantics
A list selector selects the nodes that are selected by at least one
of the selector entries in the list and yields the concatenation of
the lists (in the order of the selector entries) of nodes selected by
the selector entries. Note that any node selected in more than one
of the selector entries is kept as many times in the node list.
To be valid, integer values in the element-index and slice-index
components MUST be in the I-JSON range of exact values, see
Section 3.1.
Examples
JSON document:
["a", "b", "c", "d", "e", "f", "g"]
Queries:
+========+========+========+============+
| Query | Result | Result | Comment |
| | | Paths | |
+========+========+========+============+
| $[0, | "a" | $[0] | Indices |
| 3] | "d" | $[3] | |
+--------+--------+--------+------------+
| $[0:2, | "a" | $[0] | Slice and |
| 5] | "b" | $[1] | index |
| | "f" | $[5] | |
+--------+--------+--------+------------+
| $[0, | "a" | $[0] | Duplicated |
| 0] | "a" | $[0] | entries |
+--------+--------+--------+------------+
Table 14: List selector examples
3.6. Semantics of null
Note that JSON null is treated the same as any other JSON value: it
is not taken to mean "undefined" or "missing".
Examples
JSON document:
{"a": null, "b": [null], "c": [{}], "null": 1}
Queries:
+===================+========+===========+====================+
| Query | Result | Result | Comment |
| | | Paths | |
+===================+========+===========+====================+
| $.a | null | $['a'] | Object value |
+-------------------+--------+-----------+--------------------+
| $.a[0] | | | null used as array |
+-------------------+--------+-----------+--------------------+
| $.a.d | | | null used as |
| | | | object |
+-------------------+--------+-----------+--------------------+
| $.b[0] | null | $['b'][0] | Array value |
+-------------------+--------+-----------+--------------------+
| $.b[*] | null | $['b'][0] | Array value |
+-------------------+--------+-----------+--------------------+
| $.b[?@] | null | $['b'][0] | Existence |
+-------------------+--------+-----------+--------------------+
| $.b[?@==null] | null | $['b'][0] | Comparison |
+-------------------+--------+-----------+--------------------+
| $.c[?(@.d==null)] | | | Comparison with |
| | | | "missing" value |
+-------------------+--------+-----------+--------------------+
| $.null | 1 | $['null'] | Not JSON null at |
| | | | all, just a string |
| | | | as object key |
+-------------------+--------+-----------+--------------------+
Table 15: Examples involving (or not involving) null
3.7. Normalized Paths
A Normalized Path is a JSONPath with restricted syntax that A Normalized Path is a JSONPath with restricted syntax that
identifies a node by providing a query that results in exactly that identifies a node by providing a query that results in exactly that
node. For example, the JSONPath expression $.book[?(@.price<10)] node. For example, the JSONPath expression $.book[?(@.price<10)]
could select two values with Normalized Paths $['book'][3] and could select two values with Normalized Paths $['book'][3] and
$['book'][5]. For a given JSON document, there is a one to one $['book'][5]. For a given JSON document, there is a one to one
correspondence between the document's nodes and the Normalized Paths correspondence between the document's nodes and the Normalized Paths
that identify these nodes. that identify these nodes.
A JSONPath implementation may output Normalized Paths instead of, or A JSONPath implementation may output Normalized Paths instead of, or
skipping to change at page 26, line 14 skipping to change at page 35, line 14
The syntax of Normalized Paths is restricted so that there is one and The syntax of Normalized Paths is restricted so that there is one and
only one way of representing any given Normalized Path. Putting this only one way of representing any given Normalized Path. Putting this
another way, for any two distinct Normalized Paths, a JSON document another way, for any two distinct Normalized Paths, a JSON document
exists that will yield distinct results when the Normalized Paths are exists that will yield distinct results when the Normalized Paths are
applied to it. applied to it.
Certain characters are escaped, in one and only one way; all other Certain characters are escaped, in one and only one way; all other
characters are unescaped. characters are unescaped.
Normalized Paths are Singular Paths. Not all Singular Paths are
Normalized Paths: $[-3], for example, is a Singular Path, but not a
Normalized Path.
normalized-path = root-selector *(normal-index-selector) normalized-path = root-selector *(normal-index-selector)
normal-index-selector = "[" (normal-quoted-member-name / normal-element-index) "]" normal-index-selector = "[" (normal-quoted-member-name / normal-element-index) "]"
normal-quoted-member-name = %x27 *normal-single-quoted %x27 ; 'string' normal-quoted-member-name = %x27 *normal-single-quoted %x27 ; 'string'
normal-single-quoted = normal-unescaped / normal-single-quoted = normal-unescaped /
ESC normal-escapable ESC normal-escapable
normal-unescaped = %x20-26 / ; omit control codes normal-unescaped = %x20-26 / ; omit control codes
%x28-5B / ; omit ' %x28-5B / ; omit '
%x5D-10FFFF ; omit \ %x5D-10FFFF ; omit \
normal-escapable = ( %x62 / %x66 / %x6E / %x72 / %x74 / ; \b \f \n \r \t normal-escapable = ( %x62 / %x66 / %x6E / %x72 / %x74 / ; \b \f \n \r \t
; b / ; BS backspace U+0008 ; b / ; BS backspace U+0008
skipping to change at page 26, line 42 skipping to change at page 36, line 5
normal-hexchar = "0" "0" normal-hexchar = "0" "0"
( (
("0" %x30-37) / ; "00"-"07" ("0" %x30-37) / ; "00"-"07"
("0" %x62) / ; "0b" ; omit U+0008-U+000A ("0" %x62) / ; "0b" ; omit U+0008-U+000A
("0" %x65-66) / ; "0e"-"0f" ; omit U+000C-U+000D ("0" %x65-66) / ; "0e"-"0f" ; omit U+000C-U+000D
("1" normal-HEXDIG) ("1" normal-HEXDIG)
) )
normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f"
normal-element-index = "0" / (DIGIT1 *DIGIT) ; non-negative decimal integer normal-element-index = "0" / (DIGIT1 *DIGIT) ; non-negative decimal integer
Examples
+============+=================+==================+
| Path | Normalized Path | Comment |
+============+=================+==================+
| $.a | $['a'] | Object value |
+------------+-----------------+------------------+
| $[1] | $[1] | Array index |
+------------+-----------------+------------------+
| $.a.b[1:2] | $['a']['b'][1] | Nested structure |
+------------+-----------------+------------------+
Table 16: Normalized Path examples
4. IANA Considerations 4. IANA Considerations
4.1. Registration of Media Type application/jsonpath 4.1. Registration of Media Type application/jsonpath
IANA is requested to register the following media type [RFC6838]: IANA is requested to register the following media type [RFC6838]:
Type name: application Type name: application
Subtype name: jsonpath Subtype name: jsonpath
skipping to change at page 27, line 25 skipping to change at page 37, line 4
Applications that use this media type: Applications that need to Applications that use this media type: Applications that need to
convey queries in JSON data convey queries in JSON data
Fragment identifier considerations: N/A Fragment identifier considerations: N/A
Additional information: Deprecated alias names for this type: N/A Additional information: Deprecated alias names for this type: N/A
Magic number(s): N/A Magic number(s): N/A
File extension(s): N/A File extension(s): N/A
Macintosh file type code(s): N/A Macintosh file type code(s): N/A
Person & email address to contact for further information: Person & email address to contact for further information:
iesg@ietf.org iesg@ietf.org
Intended usage: COMMON Intended usage: COMMON
Restrictions on usage: N/A Restrictions on usage: N/A
Author: JSONPath WG Author: JSONPath WG
Change controller: IESG Change controller: IESG
Provisional registration? (standards tree only): no Provisional registration? (standards tree only): no
5. Security Considerations 5. Security Considerations
This section gives security considerations, as required by [RFC3552]. Security considerations for JSONPath can stem from
* attack vectors on JSONPath implementations, and
* the way JSONPath is used in security-relevant mechanisms.
5.1. Attack vectors on JSONPath Implementations
Historically, JSONPath has often been implemented by feeding parts of
the query to an underlying programming language engine, e.g.,
JavaScript. This approach is well known to lead to injection attacks
and would require perfect input validation to prevent these attacks
(see Section 12 of [RFC8259] for similar considerations for JSON
itself). Instead, JSONPath implementations need to implement the
entire syntax of the query without relying on the parsers of
programming language engines.
Attacks on availability may attempt to trigger unusually expensive
runtime performance exhibited by certain implementations in certain
cases. (See Section 10 of [RFC8949] for issues in hash-table
implementations, and Section 8 of
[I-D.draft-bormann-jsonpath-iregexp] for performance issues in
regular expression implementations.) Implementers need to be aware
that good average performance is not sufficient as long as an
attacker can choose to submit specially crafted JSONPath queries that
trigger surprisingly high, possibly exponential, CPU usage.
5.2. Attacks on Security Mechanisms that Employ JSONPath
Where JSONPath is used as a part of a security mechanism, attackers
can attempt to evoke unexpected behavior, or take advantage of
differences in behavior between JSONPath implementations.
This also applies to underlying technologies such as UTF-8 (see
Section 10 of [RFC3629]), the Unicode character set, and JSON. A
characteristic of JSON that can lead to varying results is the fact
that JSON objects are unordered; therefore, the order in which
results of a JSONPath query reflect the presence of JSON object
members can vary with implementations.
6. References 6. References
6.1. Normative References 6.1. Normative References
[I-D.draft-bormann-jsonpath-iregexp] [I-D.draft-bormann-jsonpath-iregexp]
Bormann, C. and T. Bray, "I-Regexp: An Interoperable Bormann, C. and T. Bray, "I-Regexp: An Interoperable
Regexp Format", Work in Progress, Internet-Draft, draft- Regexp Format", Work in Progress, Internet-Draft, draft-
bormann-jsonpath-iregexp-03, 7 March 2022, bormann-jsonpath-iregexp-03, 7 March 2022,
<https://www.ietf.org/archive/id/draft-bormann-jsonpath- <https://www.ietf.org/archive/id/draft-bormann-jsonpath-
skipping to change at page 29, line 9 skipping to change at page 39, line 29
[ECMA-262] Ecma International, "ECMAScript Language Specification, [ECMA-262] Ecma International, "ECMAScript Language Specification,
Standard ECMA-262, Third Edition", December 1999, Standard ECMA-262, Third Edition", December 1999,
<http://www.ecma-international.org/publications/files/ <http://www.ecma-international.org/publications/files/
ECMA-ST-ARCH/ECMA- ECMA-ST-ARCH/ECMA-
262,%203rd%20edition,%20December%201999.pdf>. 262,%203rd%20edition,%20December%201999.pdf>.
[JSONPath-orig] [JSONPath-orig]
Gössner, S., "JSONPath — XPath for JSON", 21 February Gössner, S., "JSONPath — XPath for JSON", 21 February
2007, <https://goessner.net/articles/JsonPath/>. 2007, <https://goessner.net/articles/JsonPath/>.
[RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC
Text on Security Considerations", BCP 72, RFC 3552,
DOI 10.17487/RFC3552, July 2003,
<https://www.rfc-editor.org/info/rfc3552>.
[RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed.,
"JavaScript Object Notation (JSON) Pointer", RFC 6901, "JavaScript Object Notation (JSON) Pointer", RFC 6901,
DOI 10.17487/RFC6901, April 2013, DOI 10.17487/RFC6901, April 2013,
<https://www.rfc-editor.org/info/rfc6901>. <https://www.rfc-editor.org/info/rfc6901>.
[RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object
Representation (CBOR)", STD 94, RFC 8949,
DOI 10.17487/RFC8949, December 2020,
<https://www.rfc-editor.org/info/rfc8949>.
[SLICE] "Slice notation", n.d., [SLICE] "Slice notation", n.d.,
<https://github.com/tc39/proposal-slice-notation>. <https://github.com/tc39/proposal-slice-notation>.
[XPath] Berglund, A., Boag, S., Chamberlin, D., Fernandez, M., [XPath] Berglund, A., Boag, S., Chamberlin, D., Fernandez, M.,
Kay, M., Robie, J., and J. Simeon, "XML Path Language Kay, M., Robie, J., and J. Simeon, "XML Path Language
(XPath) 2.0 (Second Edition)", World Wide Web Consortium (XPath) 2.0 (Second Edition)", World Wide Web Consortium
Recommendation REC-xpath20-20101214, 14 December 2010, Recommendation REC-xpath20-20101214, 14 December 2010,
<https://www.w3.org/TR/2010/REC-xpath20-20101214>. <https://www.w3.org/TR/2010/REC-xpath20-20101214>.
Appendix A. Inspired by XPath Appendix A. Inspired by XPath
skipping to change at page 31, line 4 skipping to change at page 41, line 24
($['store']['book'][0]['title']), a lightweight/limited, and a more ($['store']['book'][0]['title']), a lightweight/limited, and a more
heavyweight syntax replacing XPath's / within query expressions. heavyweight syntax replacing XPath's / within query expressions.
Both JSONPath and XPath use * for a wildcard. The descendant Both JSONPath and XPath use * for a wildcard. The descendant
operator .., borrowed from [E4X], is similar to XPath's //. The array operator .., borrowed from [E4X], is similar to XPath's //. The array
slicing construct [start:end:step] is unique to JSONPath, inspired by slicing construct [start:end:step] is unique to JSONPath, inspired by
[SLICE] from ECMASCRIPT 4. [SLICE] from ECMASCRIPT 4.
Filter expressions are supported via the syntax ?(<boolean expr>) as Filter expressions are supported via the syntax ?(<boolean expr>) as
in in
$.store.book[?(@.price < 10)].title $.store.book[?(@.price < 10)].title
Table 7 extends Table 1 by providing a comparison with similar XPath Table 17 extends Table 1 by providing a comparison with similar XPath
concepts. concepts.
+==========+==================+===================================+ +==========+==================+===================================+
| XPath | JSONPath | Description | | XPath | JSONPath | Description |
+==========+==================+===================================+ +==========+==================+===================================+
| / | $ | the root XML element | | / | $ | the root XML element |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| . | @ | the current XML element | | . | @ | the current XML element |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| / | . or [] | child operator | | / | . or [] | child operator |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| .. | n/a | parent operator | | .. | n/a | parent operator |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| // | .. | nested descendants (JSONPath | | // | .. | descendants (JSONPath borrows |
| | | borrows this syntax from E4X) | | | | this syntax from E4X) |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| * | * | wildcard: All XML elements | | * | * | wildcard: All XML elements |
| | | regardless of their names | | | | regardless of their names |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| @ | n/a | attribute access: JSON values do | | @ | n/a | attribute access: JSON values do |
| | | not have attributes | | | | not have attributes |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| [] | [] | subscript operator used to | | [] | [] | subscript operator used to |
| | | iterate over XML element | | | | iterate over XML element |
| | | collections and for predicates | | | | collections and for predicates |
skipping to change at page 31, line 50 skipping to change at page 42, line 46
| | | from ES4 | | | | from ES4 |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| [] | ?() | applies a filter (script) | | [] | ?() | applies a filter (script) |
| | | expression | | | | expression |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| seamless | n/a | expression engine | | seamless | n/a | expression engine |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| () | n/a | grouping | | () | n/a | grouping |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
Table 7: XPath syntax compared to JSONPath Table 17: XPath syntax compared to JSONPath
For further illustration, Table 8 shows some XPath expressions and For further illustration, Table 18 shows some XPath expressions and
their JSONPath equivalents. their JSONPath equivalents.
+======================+========================+===================+ +======================+========================+===================+
| XPath | JSONPath | Result | | XPath | JSONPath | Result |
+======================+========================+===================+ +======================+========================+===================+
| /store/book/author | $.store.book[*].author | the authors of | | /store/book/author | $.store.book[*].author | the authors of |
| | | all books in | | | | all books in |
| | | the store | | | | the store |
+----------------------+------------------------+-------------------+ +----------------------+------------------------+-------------------+
| //author | $..author | all authors | | //author | $..author | all authors |
skipping to change at page 32, line 52 skipping to change at page 43, line 49
+----------------------+------------------------+-------------------+ +----------------------+------------------------+-------------------+
| //* | $..* | all elements in | | //* | $..* | all elements in |
| | | XML document; | | | | XML document; |
| | | all member | | | | all member |
| | | values and | | | | values and |
| | | array elements | | | | array elements |
| | | contained in | | | | contained in |
| | | input value | | | | input value |
+----------------------+------------------------+-------------------+ +----------------------+------------------------+-------------------+
Table 8: Example XPath expressions and their JSONPath equivalents Table 18: Example XPath expressions and their JSONPath equivalents
XPath has a lot more functionality (location paths in unabbreviated XPath has a lot more functionality (location paths in unabbreviated
syntax, operators and functions) than listed in this comparison. syntax, operators and functions) than listed in this comparison.
Moreover, there are significant differences in how the subscript Moreover, there are significant differences in how the subscript
operator works in XPath and JSONPath: operator works in XPath and JSONPath:
* Square brackets in XPath expressions always operate on the _node * Square brackets in XPath expressions always operate on the _node
set_ resulting from the previous path fragment. Indices always set_ resulting from the previous path fragment. Indices always
start at 1. start at 1.
 End of changes. 71 change blocks. 
203 lines changed or deleted 598 lines changed or added

This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/