rfc9535v5.txt   rfc9535.txt 
skipping to change at line 134 skipping to change at line 134
B.1. JSONPath and XPath B.1. JSONPath and XPath
Appendix C. JSON Pointer Appendix C. JSON Pointer
Acknowledgements Acknowledgements
Contributors Contributors
Authors' Addresses Authors' Addresses
1. Introduction 1. Introduction
JSON [RFC8259] is a popular representation format for structured data JSON [RFC8259] is a popular representation format for structured data
values. JSONPath defines a string syntax for selecting and values. JSONPath defines a string syntax for selecting and
extracting JSON [RFC8259] values from within a given JSON value. extracting JSON values from within a given JSON value.
In relation to JSON Pointer [RFC6901], JSONPath is not intended as a In relation to JSON Pointer [RFC6901], JSONPath is not intended as a
replacement but as a more powerful companion. See Appendix C. replacement but as a more powerful companion. See Appendix C.
1.1. Terminology 1.1. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in "OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
skipping to change at line 739 skipping to change at line 739
slice-selector / slice-selector /
index-selector / index-selector /
filter-selector filter-selector
The syntax and semantics of each kind of selector are defined below. The syntax and semantics of each kind of selector are defined below.
2.3.1. Name Selector 2.3.1. Name Selector
2.3.1.1. Syntax 2.3.1.1. Syntax
A name selector '<name>' selects one object member value at most. A name selector '<name>' selects at most one object member value.
In contrast to JSON, the JSONPath syntax allows strings to be In contrast to JSON, the JSONPath syntax allows strings to be
enclosed in _single_ or _double_ quotes. enclosed in _single_ or _double_ quotes.
name-selector = string-literal name-selector = string-literal
string-literal = %x22 *double-quoted %x22 / ; "string" string-literal = %x22 *double-quoted %x22 / ; "string"
%x27 *single-quoted %x27 ; 'string' %x27 *single-quoted %x27 ; 'string'
double-quoted = unescaped / double-quoted = unescaped /
skipping to change at line 963 skipping to change at line 963
The example above with the query $.o[*, *] shows that the wildcard The example above with the query $.o[*, *] shows that the wildcard
selector may produce nodelists in distinct orders each time it selector may produce nodelists in distinct orders each time it
appears in the child segment when it is applied to an object node appears in the child segment when it is applied to an object node
with two or more members (but not when it is applied to object nodes with two or more members (but not when it is applied to object nodes
with fewer than two members or to array nodes). with fewer than two members or to array nodes).
2.3.3. Index Selector 2.3.3. Index Selector
2.3.3.1. Syntax 2.3.3.1. Syntax
An index selector <index> matches one array element value at most. An index selector <index> matches at most one array element value.
index-selector = int ; decimal integer index-selector = int ; decimal integer
int = "0" / int = "0" /
(["-"] DIGIT1 *DIGIT) ; - optional (["-"] DIGIT1 *DIGIT) ; - optional
DIGIT1 = %x31-39 ; 1-9 non-zero digit DIGIT1 = %x31-39 ; 1-9 non-zero digit
Applying the numerical index-selector selects the corresponding Applying the numerical index-selector selects the corresponding
element. JSONPath allows it to be negative (see Section 2.3.3.2). element. JSONPath allows it to be negative (see Section 2.3.3.2).
skipping to change at line 1046 skipping to change at line 1046
The slice selector consists of three optional decimal integers The slice selector consists of three optional decimal integers
separated by colons. The second colon can be omitted when the third separated by colons. The second colon can be omitted when the third
integer is omitted. integer is omitted.
To be valid, the integers provided MUST be in the I-JSON range of To be valid, the integers provided MUST be in the I-JSON range of
exact values (see Section 2.1). exact values (see Section 2.1).
2.3.4.2. Semantics 2.3.4.2. Semantics
The slice selector was inspired by the slice operator of ECMAScript 4 The slice selector was inspired by the slice operator that was
(ES4), which was deprecated in 2014, and that of Python. proposed for ECMAScript 4 (ES4), which was never released, and that
of Python.
2.3.4.2.1. Informal Introduction 2.3.4.2.1. Informal Introduction
This section is informative. This section is informative.
Array slicing is inspired by the behavior of the Array slicing is inspired by the behavior of the
Array.prototype.slice method of the JavaScript language, as defined Array.prototype.slice method of the JavaScript language, as defined
by the ECMA-262 standard [ECMA-262], with the addition of the step by the ECMA-262 standard [ECMA-262], with the addition of the step
parameter, which is inspired by the Python slice expression. parameter, which is inspired by the Python slice expression.
skipping to change at line 1493 skipping to change at line 1494
JSON: JSON:
{ {
"obj": {"x": "y"}, "obj": {"x": "y"},
"arr": [2, 3] "arr": [2, 3]
} }
Comparisons: Comparisons:
+========================+========+============================+ +========================+========+========================+
| Comparison | Result | Comment | | Comparison | Result | Comment |
+========================+========+============================+ +========================+========+========================+
| $.absent1 == $.absent2 | true | Empty nodelists | | $.absent1 == $.absent2 | true | Empty nodelists |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.absent1 <= $.absent2 | true | == implies <= | | $.absent1 <= $.absent2 | true | == implies <= |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.absent == 'g' | false | Empty nodelist | | $.absent == 'g' | false | Empty nodelist |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.absent1 != $.absent2 | false | Empty nodelists | | $.absent1 != $.absent2 | false | Empty nodelists |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.absent != 'g' | true | Empty nodelist | | $.absent != 'g' | true | Empty nodelist |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 1 <= 2 | true | Numeric comparison | | 1 <= 2 | true | Numeric comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 1 > 2 | false | Strict, numeric comparison | | 1 > 2 | false | Numeric comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 13 == '13' | false | Type mismatch | | 13 == '13' | false | Type mismatch |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 'a' <= 'b' | true | String comparison | | 'a' <= 'b' | true | String comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 'a' > 'b' | false | Strict, string comparison | | 'a' > 'b' | false | String comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj == $.arr | false | Type mismatch | | $.obj == $.arr | false | Type mismatch |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj != $.arr | true | Type mismatch | | $.obj != $.arr | true | Type mismatch |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj == $.obj | true | Object comparison | | $.obj == $.obj | true | Object comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj != $.obj | false | Object comparison | | $.obj != $.obj | false | Object comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.arr == $.arr | true | Array comparison | | $.arr == $.arr | true | Array comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.arr != $.arr | false | Array comparison | | $.arr != $.arr | false | Array comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj == 17 | false | Type mismatch | | $.obj == 17 | false | Type mismatch |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj != 17 | true | Type mismatch | | $.obj != 17 | true | Type mismatch |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj <= $.arr | false | Objects and arrays do not | | $.obj <= $.arr | false | Objects and arrays do |
| | | offer < comparison | | | | not offer < comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj < $.arr | false | Objects and arrays do not | | $.obj < $.arr | false | Objects and arrays do |
| | | offer < comparison | | | | not offer < comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.obj <= $.obj | true | == implies <= | | $.obj <= $.obj | true | == implies <= |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| $.arr <= $.arr | true | == implies <= | | $.arr <= $.arr | true | == implies <= |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 1 <= $.arr | false | Arrays do not offer < | | 1 <= $.arr | false | Arrays do not offer < |
| | | comparison | | | | comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 1 >= $.arr | false | Arrays do not offer < | | 1 >= $.arr | false | Arrays do not offer < |
| | | comparison | | | | comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 1 > $.arr | false | Arrays do not offer < | | 1 > $.arr | false | Arrays do not offer < |
| | | comparison | | | | comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| 1 < $.arr | false | Arrays do not offer < | | 1 < $.arr | false | Arrays do not offer < |
| | | comparison | | | | comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| true <= true | true | == implies <= | | true <= true | true | == implies <= |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
| true > true | false | Booleans do not offer < | | true > true | false | Booleans do not offer |
| | | comparison | | | | < comparison |
+------------------------+--------+----------------------------+ +------------------------+--------+------------------------+
Table 11: Comparison Examples Table 11: Comparison Examples
The second set of examples shows some complete JSONPath queries that The second set of examples shows some complete JSONPath queries that
make use of filter selectors and the results of evaluating these make use of filter selectors and the results of evaluating these
queries on a given JSON value as input. (Note: Two of the queries queries on a given JSON value as input. (Note: Two of the queries
employ function extensions; please see Sections 2.4.6 and 2.4.7 for employ function extensions; please see Sections 2.4.6 and 2.4.7 for
details about these.) details about these.)
JSON: JSON:
skipping to change at line 1967 skipping to change at line 1968
$[?value(@..color) == "red"] $[?value(@..color) == "red"]
Its only argument is an instance of NodesType (possibly taken from a Its only argument is an instance of NodesType (possibly taken from a
filter-query, as in the example above). The result is an instance of filter-query, as in the example above). The result is an instance of
ValueType. ValueType.
* If the argument contains a single node, the result is the value of * If the argument contains a single node, the result is the value of
the node. the node.
* If the argument is the special result Nothing or contains multiple * If the argument is the empty nodelist or contains multiple nodes,
nodes, the result is Nothing. the result is Nothing.
Note: A singular query may be used anywhere where a ValueType is Note: A singular query may be used anywhere where a ValueType is
expected, so there is no need to use the value() function extension expected, so there is no need to use the value() function extension
with a singular query. with a singular query.
2.4.9. Examples 2.4.9. Examples
+======================+==========================================+ +======================+==========================================+
| Query | Comment | | Query | Comment |
+======================+==========================================+ +======================+==========================================+
skipping to change at line 2427 skipping to change at line 2428
+-------------+-----------------+--------------------------+ +-------------+-----------------+--------------------------+
| $["\u0061"] | $['a'] | Unicode character | | $["\u0061"] | $['a'] | Unicode character |
+-------------+-----------------+--------------------------+ +-------------+-----------------+--------------------------+
Table 18: Normalized Path Examples Table 18: Normalized Path Examples
3. IANA Considerations 3. IANA Considerations
3.1. Registration of Media Type application/jsonpath 3.1. Registration of Media Type application/jsonpath
IANA is requested to register the following media type [RFC6838]: IANA has registered the following media type [RFC6838]:
Type name: application Type name: application
Subtype name: jsonpath Subtype name: jsonpath
Required parameters: N/A Required parameters: N/A
Optional parameters: N/A Optional parameters: N/A
Encoding considerations: binary (UTF-8) Encoding considerations: binary (UTF-8)
skipping to change at line 3032 skipping to change at line 3033
| seamless | n/a | expression engine | | seamless | n/a | expression engine |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
| () | n/a | grouping | | () | n/a | grouping |
+----------+------------------+-----------------------------------+ +----------+------------------+-----------------------------------+
Table 20: XPath Syntax Compared to JSONPath Table 20: XPath Syntax Compared to JSONPath
For further illustration, Table 21 shows some XPath expressions and For further illustration, Table 21 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 |
| | | all books in the | | | | of all books |
| | | store | | | | in the store |
+----------------------+------------------------+------------------+ +-----------------------+------------------------+------------------+
| //author | $..author | all authors | | //author | $..author | all authors |
+----------------------+------------------------+------------------+ +-----------------------+------------------------+------------------+
| /store/* | $.store.* | all things in | | /store/* | $.store.* | all things in |
| | | store, which are | | | | store, which |
| | | some books and a | | | | are some |
| | | red bicycle | | | | books and a |
+----------------------+------------------------+------------------+ | | | red bicycle |
| /store//price | $.store..price | the prices of | +-----------------------+------------------------+------------------+
| | | everything in | | /store//price | $.store..price | the prices of |
| | | the store | | | | everything in |
+----------------------+------------------------+------------------+ | | | the store |
| //book[3] | $..book[2] | the third book | +-----------------------+------------------------+------------------+
+----------------------+------------------------+------------------+ | //book[3] | $..book[2] | the third |
| //book[last()] | $..book[-1] | the last book in | | | | book |
| | | order | +-----------------------+------------------------+------------------+
+----------------------+------------------------+------------------+ | //book[last()] | $..book[-1] | the last book |
| //book[position()<3] | $..book[0,1] | the first two | | | | in order |
| | $..book[:2] | books | +-----------------------+------------------------+------------------+
+----------------------+------------------------+------------------+ | //book[position()<3] | $..book[0,1] | the first two |
| //book[isbn] | $..book[?@.isbn] | filter all books | | | $..book[:2] | books |
| | | with an ISBN | +-----------------------+------------------------+------------------+
| | | number | | //book[isbn] | $..book[?@.isbn] | filter all |
+----------------------+------------------------+------------------+ | | | books with an |
| //book[price<10] | $..book[?@.price<10] | filter all books | | | | ISBN number |
| | | cheaper than 10 | +-----------------------+------------------------+------------------+
+----------------------+------------------------+------------------+ | //book[price<10] | $..book[?@.price<10] | filter all |
| //* | $..* | all elements in | | | | books cheaper |
| | | an XML document; | | | | than 10 |
| | | all member | +-----------------------+------------------------+------------------+
| | | values and array | | //* | $..* | all elements |
| | | elements | | | | in an XML |
| | | contained in | | | | document; all |
| | | input value | | | | member values |
+----------------------+------------------------+------------------+ | | | and array |
| | | elements |
| | | contained in |
| | | input value |
+-----------------------+------------------------+------------------+
Table 21: Example XPath Expressions and Their JSONPath Equivalents Table 21: 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. 9 change blocks. 
116 lines changed or deleted 121 lines changed or added

This html diff was produced by rfcdiff 1.48.