rfc9535.original.xml   rfc9535.xml 
<?xml version='1.0' encoding='utf-8'?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc [ <!DOCTYPE rfc [
<!ENTITY nbsp "&#160;"> <!ENTITY nbsp "&#160;">
<!ENTITY zwsp "&#8203;"> <!ENTITY zwsp "&#8203;">
<!ENTITY nbhy "&#8209;"> <!ENTITY nbhy "&#8209;">
<!ENTITY wj "&#8288;"> <!ENTITY wj "&#8288;">
]> ]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.43 (Ruby 3.2. 2) --> <!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.43 (Ruby 3.2. 2) -->
<?rfc comments="yes"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft
-ietf-jsonpath-base-21" category="std" consensus="true" submissionType="IETF" xm -ietf-jsonpath-base-21" number="9535" submissionType="IETF" category="std" conse
l:lang="en" tocDepth="4" tocInclude="true" sortRefs="true" symRefs="true" versio nsus="true" xml:lang="en" tocDepth="4" tocInclude="true" sortRefs="true" symRefs
n="3"> ="true" updates="" obsoletes="" version="3">
<!-- xml2rfc v2v3 conversion 3.18.0 --> <!-- xml2rfc v2v3 conversion 3.18.0 -->
<front> <front>
<title abbrev="JSONPath">JSONPath: Query expressions for JSON</title> <title abbrev="JSONPath">JSONPath: Query Expressions for JSON</title>
<seriesInfo name="Internet-Draft" value="draft-ietf-jsonpath-base-21"/> <seriesInfo name="RFC" value="9535"/>
<author initials="S." surname="Gössner" fullname="Stefan Gössner" role="edit or"> <author initials="S." surname="Gössner" fullname="Stefan Gössner" role="edit or">
<organization>Fachhochschule Dortmund</organization> <organization>Fachhochschule Dortmund</organization>
<address> <address>
<postal> <postal>
<street>Sonnenstraße 96</street> <street>Sonnenstraße 96</street>
<city>Dortmund</city> <city>Dortmund</city>
<code>D-44139</code> <code>D-44139</code>
<country>Germany</country> <country>Germany</country>
</postal> </postal>
<email>stefan.goessner@fh-dortmund.de</email> <email>stefan.goessner@fh-dortmund.de</email>
</address> </address>
</author> </author>
<author initials="G." surname="Normington" fullname="Glyn Normington" role=" editor"> <author initials="G." surname="Normington" fullname="Glyn Normington" role=" editor">
<organization/> <organization/>
<address> <address>
<postal> <postal>
<street/> <street/>
<city>Winchester</city> <city>Winchester</city>
<region/> <region/>
<code/> <code/>
<country>UK</country> <country>United Kingdom</country>
</postal> </postal>
<phone/> <phone/>
<email>glyn.normington@gmail.com</email> <email>glyn.normington@gmail.com</email>
</address> </address>
</author> </author>
<author initials="C." surname="Bormann" fullname="Carsten Bormann" role="edi tor"> <author initials="C." surname="Bormann" fullname="Carsten Bormann" role="edi tor">
<organization>Universität Bremen TZI</organization> <organization>Universität Bremen TZI</organization>
<address> <address>
<postal> <postal>
<street>Postfach 330440</street> <street>Postfach 330440</street>
<city>Bremen</city> <city>Bremen</city>
<code>D-28359</code> <code>D-28359</code>
<country>Germany</country> <country>Germany</country>
</postal> </postal>
<phone>+49-421-218-63921</phone> <phone>+49-421-218-63921</phone>
<email>cabo@tzi.org</email> <email>cabo@tzi.org</email>
</address> </address>
</author> </author>
<date year="2023"/> <date year="2024" month="February"/>
<area>ART</area> <area>art</area>
<workgroup>JSONPath WG</workgroup> <workgroup>jsonpath</workgroup>
<keyword>JSON</keyword> <keyword>JSON</keyword>
<abstract> <abstract>
<?line 145?> <t>JSONPath defines a string syntax for selecting and extracting JSON (RFC 8259)
values from within a given JSON value.</t>
<t>JSONPath defines a string syntax for selecting and extracting JSON (RFC 8259)
values
from a JSON value.</t>
</abstract> </abstract>
<note removeInRFC="true">
<name>About This Document</name>
<t>
Status information for this document may be found at <eref target="https
://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/"/>.
</t>
<t>
Discussion of this document takes place on the
JSON Path Working Group mailing list (<eref target="mailto:jsonpath@ietf
.org"/>),
which is archived at <eref target="https://mailarchive.ietf.org/arch/bro
wse/jsonpath/"/>.
Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/jsonpat
h/"/>.
</t>
<t>Source for this draft and an issue tracker can be found at
<eref target="https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-ba
se"/>.</t>
</note>
</front> </front>
<middle> <middle>
<?line 150?>
<!-- define an ALD to simplify below -->
<!-- use as {: unnumbered} -->
<!-- editorial issue: lots of complicated nesting of quotes, as in -->
<!-- `"13 == '13'"` or `$`. We probably should find a simpler style -->
<section anchor="introduction"> <section anchor="introduction">
<name>Introduction</name> <name>Introduction</name>
<t>JSON <xref target="RFC8259"/> is a popular representation <t>JSON <xref target="RFC8259"/> is a popular representation
format for structured data values. format for structured data values.
JSONPath defines a string syntax for selecting and extracting JSON values JSONPath defines a string syntax for selecting and extracting JSON values
from a JSON value.</t> from within a given JSON value.</t>
<t>JSONPath is not intended as a replacement for, but as a more powerful <t>In relation to JSON Pointer <xref target="RFC6901"/>, JSONPath is not intende
companion to, JSON Pointer <xref target="RFC6901"/>. See <xref target="json-poin d as a replacement but as a more powerful
ter"/>.</t> companion. See <xref target="json-pointer"/>.</t>
<section anchor="terminology"> <section anchor="terminology">
<name>Terminology</name> <name>Terminology</name>
<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp <t>
14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECO IRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
MMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be i RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
nterpreted as "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and be interpreted as
only when, they described in BCP&nbsp;14 <xref target="RFC2119"/> <xref target="RFC8174"/>
appear in all capitals, as shown here.</t> when, and only when, they appear in all capitals, as shown here.
<?line -18?> </t>
<t>The grammatical rules in this document are to be interpreted as ABNF, <t>The grammatical rules in this document are to be interpreted as ABNF,
as described in <xref target="RFC5234"/>. as described in <xref target="RFC5234"/>.
ABNF terminal values in this document define Unicode scalar values rather than ABNF terminal values in this document define Unicode scalar values rather than
their UTF-8 encoding. their UTF-8 encoding.
For example, the Unicode PLACE OF INTEREST SIGN (U+2318) would be defined For example, the Unicode PLACE OF INTEREST SIGN (U+2318) would be defined
in ABNF as <tt>%x2318</tt>.</t> in ABNF as <tt>%x2318</tt>.</t>
<t>Functions are referred to using the function name followed by a pair <t>Functions are referred to using the function name followed by a pair
of parentheses, as in <tt>fname()</tt>.</t> of parentheses, as in <tt>fname()</tt>.</t>
<t>The terminology of <xref target="RFC8259"/> applies except where clar ified below. <t>The terminology of <xref target="RFC8259"/> applies except where clar ified below.
The terms "Primitive" and "Structured" are used to group The terms "primitive" and "structured" are used to group
different kinds of values as in <xref section="1" sectionFormat="of" target="RFC different kinds of values as in <xref section="1" sectionFormat="of" target="RFC
8259"/>; JSON Objects and Arrays are 8259"/>. JSON objects and arrays are
structured, all other values are primitive. structured; all other values are primitive.
Definitions for "Object", "Array", "Number", and "String" remain Definitions for "object", "array", "number", and "string" remain
unchanged. unchanged.
Importantly "object" and "array" in particular do not take on a Importantly, "object" and "array" in particular do not take on a
generic meaning, such as they would in a general programming context.</t> generic meaning, such as they would in a general programming context.</t>
<t>Additional terms used in this document are defined below.</t> <t>The terminology of <xref target="RFC9485"/> applies.</t>
<t>Additional terms used in this document are defined below.</t>
<dl> <dl>
<dt>Value:</dt> <dt>Value:</dt>
<dd> <dd>
<t>As per <xref target="RFC8259"/>, a structure conforming to the ge <t>As per <xref target="RFC8259"/>, a data item conforming to the ge
neric data model of JSON, i.e., neric data model of JSON, i.e.,
composed of constituents such as structured values, namely JSON objects and arra primitive data (numbers, text strings, and the special
ys, and values null, true, and false), or structured data (JSON objects and arrays).
primitive data, namely numbers and text strings as well as the special
values null, true, and false.
<xref target="RFC8259"/> focuses on the textual representation of JSON values an d <xref target="RFC8259"/> focuses on the textual representation of JSON values an d
does not fully define the value abstraction assumed here.</t> does not fully define the value abstraction assumed here.</t>
</dd> </dd>
<dt>Member:</dt> <dt>Member:</dt>
<dd> <dd>
<t>A name/value pair in an object. (A member is not itself a value. )</t> <t>A name/value pair in an object. (A member is not itself a value. )</t>
</dd> </dd>
<dt>Name:</dt> <dt>Name:</dt>
<dd> <dd>
<t>The name (a string) in a name/value pair constituting a member. <t>The name (a string) in a name/value pair constituting a member.
skipping to change at line 159 skipping to change at line 135
<dd> <dd>
<t>An integer that identifies a specific element in an array.</t> <t>An integer that identifies a specific element in an array.</t>
</dd> </dd>
<dt>Query:</dt> <dt>Query:</dt>
<dd> <dd>
<t>Short name for a JSONPath expression.</t> <t>Short name for a JSONPath expression.</t>
</dd> </dd>
<dt>Query Argument:</dt> <dt>Query Argument:</dt>
<dd> <dd>
<t>Short name for the value a JSONPath expression is applied to. <t>Short name for the value a JSONPath expression is applied to.
(Also used for actual parameters of function-expressions.)</t> </t>
</dd> </dd>
<dt>Location:</dt> <dt>Location:</dt>
<dd> <dd>
<t>the position of a value within the query argument. This can be th ought of <t>The position of a value within the query argument. This can be th ought of
as a sequence of names and indexes navigating to the value through as a sequence of names and indexes navigating to the value through
the objects and arrays in the query argument, with the empty sequence the objects and arrays in the query argument, with the empty sequence
indicating the query argument itself. indicating the query argument itself.
A location can be represented as a Normalized Path (defined below).</t> A location can be represented as a Normalized Path (defined below).</t>
</dd> </dd>
<dt>Node:</dt> <dt>Node:</dt>
<dd> <dd>
<t>The pair of a value along with its location within the query argu ment.</t> <t>The pair of a value along with its location within the query argu ment.</t>
</dd> </dd>
<dt>Root Node:</dt> <dt>Root Node:</dt>
<dd> <dd>
<t>The unique node whose value is the entire query argument.</t> <t>The unique node whose value is the entire query argument.</t>
</dd> </dd>
<dt>Root Node Identifier:</dt> <dt>Root Node Identifier:</dt>
<dd> <dd>
<t>The expression <tt>$</tt> which refers to the root node of the qu ery argument.</t> <t>The expression <tt>$</tt>, which refers to the root node of the q uery argument.</t>
</dd> </dd>
<dt>Current Node Identifier:</dt> <dt>Current Node Identifier:</dt>
<dd> <dd>
<t>The expression <tt>@</tt> which refers to the current node in the context <t>The expression <tt>@</tt>, which refers to the current node in th e context
of the evaluation of a filter expression (described later).</t> of the evaluation of a filter expression (described later).</t>
</dd> </dd>
<dt>Children (of a node):</dt> <dt>Children (of a node):</dt>
<dd> <dd>
<t>If the node is an array, the nodes of its elements. <t>If the node is an array, the nodes of its elements; if the node i
If the node is an object, the nodes of its member values. s an object, the nodes of its member values.
If the node is neither an array nor an object, it has no children.</t> If the node is neither an array nor an object, it has no children.</t>
</dd> </dd>
<dt>Descendants (of a node):</dt> <dt>Descendants (of a node):</dt>
<dd> <dd>
<t>The children of the node, together with the children of its child ren, and so forth <t>The children of the node, together with the children of its child ren, and so forth
recursively. More formally, the "descendants" relation between nodes is the tran sitive recursively. More formally, the "descendants" relation between nodes is the tran sitive
closure of the "children" relation.</t> closure of the "children" relation.</t>
</dd> </dd>
<dt>Depth (of a descendant node within a value):</dt> <dt>Depth (of a descendant node within a value):</dt>
<dd> <dd>
<t>The number of ancestors of the node within the value. The root no de of the value has depth zero, <t>The number of ancestors of the node within the value. The root no de of the value has depth zero,
the children of the root node have depth one, their children have depth two, and so forth.</t> the children of the root node have depth one, their children have depth two, and so forth.</t>
</dd> </dd>
<dt>Nodelist:</dt> <dt>Nodelist:</dt>
<dd> <dd>
<t>A list of nodes. <t>A list of nodes.
While a nodelist can be represented in JSON, e.g. as an array, this document While a nodelist can be represented in JSON, e.g., as an array, this document
does not require or assume any particular representation.</t> does not require or assume any particular representation.</t>
</dd> </dd>
<dt>Parameter:</dt> <dt>Parameter:</dt>
<dd> <dd>
<t>Formal parameter (of a function) that can take a function argumen t <t>Formal parameter (of a function) that can take a function argumen t
(an actual parameter) in a function-expression.</t> (an actual parameter) in a function expression.</t>
</dd> </dd>
<dt>Normalized Path:</dt> <dt>Normalized Path:</dt>
<dd> <dd>
<t>A form of JSONPath expression that identifies a node in a value b y <t>A form of JSONPath expression that identifies a node in a value b y
providing a query that results in exactly that node. Each node in a providing a query that results in exactly that node. Each node in a
query argument is identified by exactly one Normalized Path (we say, the query argument is identified by exactly one Normalized Path (we say that the
Normalized Path is "unique" for that node), and, to be a Normalized Normalized Path is "unique" for that node), and to be a Normalized
Path for a specific query argument, the Normalized Path needs to identify Path for a specific query argument, the Normalized Path needs to identify
exactly one node. Similar exactly one node. This is similar
to, but syntactically different from, a JSON Pointer <xref target="RFC6901"/>. to, but syntactically different from, a JSON Pointer <xref target="RFC6901"/>.
Note: This definition is based on the syntactical definition in <xref target="no rmalized-paths"/>; Note: This definition is based on the syntactical definition in <xref target="no rmalized-paths"/>;
JSONPath expressions that identify a node in a value but do not conform to that JSONPath expressions that identify a node in a value but do not conform to that
syntax are not Normalized Paths.</t> syntax are not Normalized Paths.</t>
</dd> </dd>
<dt>Unicode Scalar Value:</dt> <dt>Unicode Scalar Value:</dt>
<dd> <dd>
<t>Any Unicode <xref target="UNICODE"/> code point except high-surro <t>Any Unicode <xref target="UNICODE"/> code point except high-surro
gate and low-surrogate code points. gate and low-surrogate code points (in other words, integers in the inclusive ba
In other words, integers in either of the inclusive base 16 ranges 0 to D7FF and se 16 ranges, either 0 to D7FF or
E000 to 10FFFF. JSONPath queries are sequences of Unicode scalar values.</t> E000 to 10FFFF). JSONPath queries are sequences of Unicode scalar values.</t>
</dd> </dd>
<dt>Segment:</dt> <dt>Segment:</dt>
<dd> <dd>
<t>One of the constructs which select children (<tt>[&lt;selectors&g <t>One of the constructs that selects children (<tt>[&lt;selectors&g
t;]</tt>) t;]</tt>)
or descendants (<tt>..[&lt;selectors&gt;]</tt>) of an input value.</t> or descendants (<tt>..&wj;[&lt;selectors&gt;]</tt>) of an input value.</t>
</dd> </dd>
<dt>Selector:</dt> <dt>Selector:</dt>
<dd> <dd>
<t>A single item within a segment that takes the input value and pro duces a nodelist <t>A single item within a segment that takes the input value and pro duces a nodelist
consisting of child nodes of the input value.</t> consisting of child nodes of the input value.</t>
</dd> </dd>
<dt>Singular Query:</dt> <dt>Singular Query:</dt>
<dd> <dd>
<t>A JSONPath expression built from segments that have been syntacti cally restricted in <t>A JSONPath expression built from segments that have been syntacti cally restricted in
a certain way (<xref target="filter-selector-syntax"/>) so that, regardless of t he input a certain way (<xref target="filter-selector-syntax"/>) so that, regardless of t he input
value, the expression produces a nodelist containing at most one node. value, the expression produces a nodelist containing at most one node.
Note: JSONPath expressions that always produce a singular nodelist but do not Note: JSONPath expressions that always produce a singular nodelist but do not
conform to the syntax in <xref target="filter-selector-syntax"/> are not Singula r Queries.</t> conform to the syntax in <xref target="filter-selector-syntax"/> are not singula r queries.</t>
</dd> </dd>
</dl> </dl>
<section anchor="json-values-as-trees-of-nodes"> <section anchor="json-values-as-trees-of-nodes">
<name>JSON Values as Trees of Nodes</name> <name>JSON Values as Trees of Nodes</name>
<t>This document models the query argument as a tree of JSON values, e ach <t>This document models the query argument as a tree of JSON values, e ach
with its own node. with its own node.
A node is either the root node or one of its descendants.</t> A node is either the root node or one of its descendants.</t>
<t>This document models the result of applying a query to the <t>This document models the result of applying a query to the
query argument as a nodelist (a list of nodes).</t> query argument as a nodelist (a list of nodes).</t>
<t>Nodes are the selectable parts of the query argument. <t>Nodes are the selectable parts of the query argument.
The only parts of an object that can be selected by a query are the The only parts of an object that can be selected by a query are the
member values. Member names and members (name/value pairs) cannot be member values. Member names and members (name/value pairs) cannot be
selected. selected.
Thus, member values have nodes, but members and member names do not. Thus, member values have nodes, but members and member names do not.
Similarly, member values are children of an object, but members and Similarly, member values are children of an object, but members and
member names are not.</t> member names are not.</t>
</section> </section>
</section> </section>
<section anchor="history"> <section anchor="history">
<name>History</name> <name>History</name>
<t>This document is based on <contact fullname="Stefan Gössner"/>'s popu <t>This document is based on <contact fullname="Stefan Gössner"/>'s popu
lar JSONPath proposal lar JSONPath proposal (dated 2007-02-21) <xref target="JSONPath-orig"/>, builds
dated 2007-02-21 <xref target="JSONPath-orig"/>, builds on the experience from t on the experience from the widespread
he widespread
deployment of its implementations, and provides a normative specification for it .</t> deployment of its implementations, and provides a normative specification for it .</t>
<t><xref target="inspired-by-xpath"/> describes how JSONPath was inspire d by XML's XPath <t><xref target="inspired-by-xpath"/> describes how JSONPath was inspire d by XML's XPath
<xref target="XPath"/>.</t> <xref target="XPath"/>.</t>
<t>JSONPath was intended as a light-weight companion to JSON <t>JSONPath was intended as a lightweight companion to JSON
implementations in programming languages such as PHP and JavaScript, implementations in programming languages such as PHP and JavaScript,
so instead of defining its own expression language, like XPath did, so instead of defining its own expression language, like XPath did,
JSONPath delegated parts of a query to the underlying JSONPath delegated parts of a query to the underlying
runtime, e.g., JavaScript's <tt>eval()</tt> function. runtime, e.g., JavaScript's <tt>eval()</tt> function.
As JSONPath was implemented in more environments, JSONPath As JSONPath was implemented in more environments, JSONPath
expressions became decreasingly portable. expressions became decreasingly portable.
For example, regular expression processing was often delegated to a For example, regular expression processing was often delegated to a
convenient regular expression engine.</t> convenient regular expression engine.</t>
<t>This document aims to remove such implementation-specific dependencie s and <t>This document aims to remove such implementation-specific dependencie s and
serve as a common JSONPath specification that can be used across serve as a common JSONPath specification that can be used across
skipping to change at line 308 skipping to change at line 283
<t>The JSON value a JSONPath query is applied to is, by definition, a <t>The JSON value a JSONPath query is applied to is, by definition, a
valid JSON value. A JSON value is often constructed by parsing valid JSON value. A JSON value is often constructed by parsing
a JSON text.</t> a JSON text.</t>
<t>The parsing of a JSON text into a JSON value and what happens if a JS ON <t>The parsing of a JSON text into a JSON value and what happens if a JS ON
text does not represent valid JSON are not defined by this document. text does not represent valid JSON are not defined by this document.
Sections <xref target="RFC8259" section="4" sectionFormat="bare"/> and <xref tar get="RFC8259" section="8" sectionFormat="bare"/> of <xref target="RFC8259"/> ide ntify specific situations that may Sections <xref target="RFC8259" section="4" sectionFormat="bare"/> and <xref tar get="RFC8259" section="8" sectionFormat="bare"/> of <xref target="RFC8259"/> ide ntify specific situations that may
conform to the grammar for JSON texts but are not interoperable uses conform to the grammar for JSON texts but are not interoperable uses
of JSON, as they may cause unpredictable behavior. of JSON, as they may cause unpredictable behavior.
This document does not attempt to define predictable This document does not attempt to define predictable
behavior for JSONPath queries in these situations.</t> behavior for JSONPath queries in these situations.</t>
<t>Specifically, the "Semantics" subsections of Sections <t>Specifically, the "Semantics" subsections of Sections
<xref format="counter" target="name-selector"/>, <xref format="counter" target=" wildcard-selector"/>, <xref format="counter" target="name-selector"/>, <xref format="counter" target=" wildcard-selector"/>,
<xref format="counter" target="filter-selector"/>, and <xref format="counter" ta rget="descendant-segment"/> describe behavior that <xref format="counter" target="filter-selector"/>, and <xref format="counter" ta rget="descendant-segment"/> describe behavior that
becomes unpredictable when the JSON value for one of the objects becomes unpredictable when the JSON value for one of the objects
under consideration was constructed out of JSON text that exhibits under consideration was constructed out of JSON text that exhibits
multiple members for a single object that share the same member name multiple members for a single object that share the same member name
("duplicate names", see <xref section="4" sectionFormat="of" target="RFC8259"/>) ("duplicate names"; see <xref section="4" sectionFormat="of" target="RFC8259"/>)
. .
Also, selecting a child by name (<xref target="name-selector"/>) and comparing s Also, when selecting a child by name (<xref target="name-selector"/>) and compar
trings ing strings
(<xref target="comparisons"/> in <xref target="filter-selector"/>) assume these (<xref target="comparisons"/>), it is assumed these
strings are sequences of Unicode scalar values, becoming unpredictable strings are sequences of Unicode scalar values; the behavior becomes unpredictab
le
if they are not (<xref section="8.2" sectionFormat="of" target="RFC8259"/>).</t> if they are not (<xref section="8.2" sectionFormat="of" target="RFC8259"/>).</t>
</section> </section>
<section anchor="overview"> <section anchor="overview">
<name>Overview of JSONPath Expressions</name> <name>Overview of JSONPath Expressions</name>
<t>A JSONPath expression is applied to a JSON value, known as the query argument. <t>A JSONPath expression is applied to a JSON value, known as the query argument.
The output is a nodelist.</t> The output is a nodelist.</t>
<t>A JSONPath expression consists of an identifier followed by a series <t>A JSONPath expression consists of an identifier followed by a series
of zero or more segments each of which contains one or more selectors.</t> of zero or more segments, each of which contains one or more selectors.</t>
<section anchor="ids"> <section anchor="ids">
<name>Identifiers</name> <name>Identifiers</name>
<t>The root node identifier <tt>$</tt> refers to the root node of the query argument, <t>The root node identifier <tt>$</tt> refers to the root node of the query argument,
i.e., to the argument as a whole.</t> i.e., to the argument as a whole.</t>
<t>The current node identifier <tt>@</tt> refers to the current node i n the context <t>The current node identifier <tt>@</tt> refers to the current node i n the context
of the evaluation of a filter expression (<xref target="filter-selector"/>).</t> of the evaluation of a filter expression (<xref target="filter-selector"/>).</t>
</section> </section>
<section anchor="segments"> <section anchor="segments">
<name>Segments</name> <name>Segments</name>
<t>Segments select children (<tt>[&lt;selectors&gt;]</tt>) or descenda nts (<tt>..[&lt;selectors&gt;]</tt>) of an input value.</t> <t>Segments select children (<tt>[&lt;selectors&gt;]</tt>) or descenda nts (<tt>..&wj;[&lt;selectors&gt;]</tt>) of an input value.</t>
<t>Segments can use <em>bracket notation</em>, for example:</t> <t>Segments can use <em>bracket notation</em>, for example:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$['store']['book'][0]['title'] $['store']['book'][0]['title']
]]></sourcecode> ]]></sourcecode>
<t>or the more compact <em>dot notation</em>, for example:</t> <t>or the more compact <em>dot notation</em>, for example:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$.store.book[0].title $.store.book[0].title
]]></sourcecode> ]]></sourcecode>
<t>Bracket notation contains a comma separated list of one or more sel ectors of any kind. <t>Bracket notation contains one or more (comma-separated) selectors o f any kind.
Selectors are detailed in the next section.</t> Selectors are detailed in the next section.</t>
<t>A JSONPath expression may use a combination of bracket and dot nota tions.</t> <t>A JSONPath expression may use a combination of bracket and dot nota tions.</t>
<t>This document treats the bracket notations as canonical and defines the shorthand dot notation in terms <t>This document treats the bracket notations as canonical and defines the shorthand dot notation in terms
of bracket notation. Examples and descriptions use shorthands where convenient.< /t> of bracket notation. Examples and descriptions use shorthand where convenient.</ t>
</section> </section>
<section anchor="selectors"> <section anchor="selectors">
<name>Selectors</name> <name>Selectors</name>
<t>A name selector, e.g. <tt>'name'</tt>, selects a named child of an <t>A name selector, e.g., <tt>'name'</tt>, selects a named child of an
object.</t> object.</t>
<t>An index selector, e.g. <tt>3</tt>, selects an indexed child of an <t>An index selector, e.g., <tt>3</tt>, selects an indexed child of an
array.</t> array.</t>
<t>A wildcard <tt>*</tt> (<xref target="wildcard-selector"/>) in the e <t>In the expression <tt>[*]</tt>, a wildcard <tt>*</tt> (<xref target
xpression <tt>[*]</tt> selects all children of a ="wildcard-selector"/>) selects all children of a
node and in the expression <tt>..[*]</tt> selects all descendants of a node.</t> node, and in the expression <tt>..[*]</tt>, it selects all descendants of a node
.</t>
<t>An array slice <tt>start:end:step</tt> (<xref target="slice"/>) sel ects a series of <t>An array slice <tt>start:end:step</tt> (<xref target="slice"/>) sel ects a series of
elements from an array, giving a start position, an end position, and elements from an array, giving a start position, an end position, and
an optional step value that moves the position from the start to the an optional step value that moves the position from the start to the
end.</t> end.</t>
<t>Filter expressions <tt>?&lt;logical-expr&gt;</tt> select certain ch <t>A filter expression <tt>?&lt;logical-expr&gt;</tt> selects certain
ildren of an object or array, as in:</t> children of an object or array, as in:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$.store.book[?@.price < 10].title $.store.book[?@.price < 10].title
]]></sourcecode> ]]></sourcecode>
</section> </section>
<section anchor="summary"> <section anchor="summary">
<name>Summary</name> <name>Summary</name>
<t><xref target="tbl-overview"/> provides a brief overview of JSONPath syntax.</t> <t><xref target="tbl-overview"/> provides a brief overview of JSONPath syntax.</t>
<table anchor="tbl-overview"> <table anchor="tbl-overview">
<name>Overview of JSONPath syntax</name> <name>Overview of JSONPath Syntax</name>
<thead> <thead>
<tr> <tr>
<th align="left">Syntax Element</th> <th align="left">Syntax Element</th>
<th align="left">Description</th> <th align="left">Description</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left"> <td align="left">
<tt>$</tt></td> <tt>$</tt></td>
skipping to change at line 393 skipping to change at line 368
<tr> <tr>
<td align="left"> <td align="left">
<tt>@</tt></td> <tt>@</tt></td>
<td align="left"> <td align="left">
<xref target="filter-selector">current node identifier</xref> (valid only within filter selectors)</td> <xref target="filter-selector">current node identifier</xref> (valid only within filter selectors)</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>[&lt;selectors&gt;]</tt></td> <tt>[&lt;selectors&gt;]</tt></td>
<td align="left"> <td align="left">
<xref target="child-segment">child segment</xref> selects zero or more children of a node; contains one or more selectors, separated by commas </td> <xref target="child-segment">child segment</xref>: selects zer o or more children of a node</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>.name</tt></td> <tt>.name</tt></td>
<td align="left">shorthand for <tt>['name']</tt></td> <td align="left">shorthand for <tt>['name']</tt></td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>.*</tt></td> <tt>.*</tt></td>
<td align="left">shorthand for <tt>[*]</tt></td> <td align="left">shorthand for <tt>[*]</tt></td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>..[&lt;selectors&gt;]</tt></td> <tt>..&wj;[&lt;selectors&gt;]</tt></td>
<td align="left"> <td align="left">
<xref target="descendant-segment">descendant segment</xref>: s elects zero or more descendants of a node; contains one or more selectors, separ ated by commas</td> <xref target="descendant-segment">descendant segment</xref>: s elects zero or more descendants of a node</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>..name</tt></td> <tt>..name</tt></td>
<td align="left">shorthand for <tt>..['name']</tt></td> <td align="left">shorthand for <tt>..['name']</tt></td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>..*</tt></td> <tt>..*</tt></td>
<td align="left">shorthand for <tt>..[*]</tt></td> <td align="left">shorthand for <tt>..[*]</tt></td>
skipping to change at line 431 skipping to change at line 406
<tr> <tr>
<td align="left"> <td align="left">
<tt>'name'</tt></td> <tt>'name'</tt></td>
<td align="left"> <td align="left">
<xref target="name-selector">name selector</xref>: selects a n amed child of an object</td> <xref target="name-selector">name selector</xref>: selects a n amed child of an object</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>*</tt></td> <tt>*</tt></td>
<td align="left"> <td align="left">
<xref target="name-selector">wildcard selector</xref>: selects all children of a node</td> <xref target="wildcard-selector">wildcard selector</xref>: sel ects all children of a node</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>3</tt></td> <tt>3</tt></td>
<td align="left"> <td align="left">
<xref target="index-selector">index selector</xref>: selects a n indexed child of an array (from 0)</td> <xref target="index-selector">index selector</xref>: selects a n indexed child of an array (from 0)</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>0:100:5</tt></td> <tt>0:100:5</tt></td>
skipping to change at line 465 skipping to change at line 440
<xref target="fnex">function extension</xref>: invokes a funct ion in a filter expression</td> <xref target="fnex">function extension</xref>: invokes a funct ion in a filter expression</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="jsonpath-examples"> <section anchor="jsonpath-examples">
<name>JSONPath Examples</name> <name>JSONPath Examples</name>
<t>This section is informative. It provides examples of JSONPath express ions.</t> <t>This section is informative. It provides examples of JSONPath express ions.</t>
<t>The examples are based on the simple JSON value shown in <t>The examples are based on the simple JSON value shown in
<xref target="fig-example-value"/>, representing a bookstore (that also has a bi cycle).</t> <xref target="fig-example-value"/>, representing a bookstore (which also has a b icycle).</t>
<figure anchor="fig-example-value"> <figure anchor="fig-example-value">
<name>Example JSON value</name> <name>Example JSON Value</name>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{ "store": { { "store": {
"book": [ "book": [
{ "category": "reference", { "category": "reference",
"author": "Nigel Rees", "author": "Nigel Rees",
"title": "Sayings of the Century", "title": "Sayings of the Century",
"price": 8.95 "price": 8.95
}, },
{ "category": "fiction", { "category": "fiction",
"author": "Evelyn Waugh", "author": "Evelyn Waugh",
skipping to change at line 504 skipping to change at line 479
"bicycle": { "bicycle": {
"color": "red", "color": "red",
"price": 399 "price": 399
} }
} }
} }
]]></sourcecode> ]]></sourcecode>
</figure> </figure>
<t><xref target="tbl-example"/> shows some JSONPath queries that might b e applied to this example and their intended results.</t> <t><xref target="tbl-example"/> shows some JSONPath queries that might b e applied to this example and their intended results.</t>
<table anchor="tbl-example"> <table anchor="tbl-example">
<name>Example JSONPath expressions and their intended results when app lied to the example JSON value</name> <name>Example JSONPath Expressions and Their Intended Results When App lied to the Example JSON Value</name>
<thead> <thead>
<tr> <tr>
<th align="left">JSONPath</th> <th align="left">JSONPath</th>
<th align="left">Intended result</th> <th align="left">Intended Result</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left"> <td align="left">
<tt>$.store.book[*].author</tt></td> <tt>$.store.book[*].author</tt></td>
<td align="left">the authors of all books in the store</td> <td align="left">the authors of all books in the store</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>$..author</tt></td> <tt>$..author</tt></td>
<td align="left">all authors</td> <td align="left">all authors</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>$.store.*</tt></td> <tt>$.store.*</tt></td>
<td align="left">all things in store, which are some books and a r ed bicycle</td> <td align="left">all things in the store, which are some books and a red bicycle</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>$.store..price</tt></td> <tt>$.store..price</tt></td>
<td align="left">the prices of everything in the store</td> <td align="left">the prices of everything in the store</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>$..book[2]</tt></td> <tt>$..book[2]</tt></td>
<td align="left">the third book</td> <td align="left">the third book</td>
skipping to change at line 580 skipping to change at line 555
<td align="left">all member values and array elements contained in the input value</td> <td align="left">all member values and array elements contained in the input value</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="jsonpath-syntax-and-semantics"> <section anchor="jsonpath-syntax-and-semantics">
<name>JSONPath Syntax and Semantics</name> <name>JSONPath Syntax and Semantics</name>
<section anchor="synsem-overview"> <section anchor="synsem-overview">
<name>Overview</name> <name>Overview</name>
<t>A JSONPath <em>expression</em> is a string which, when applied to a J <t>A JSONPath <em>expression</em> is a string that, when applied to a JS
SON value, ON value
the <em>query argument</em>, selects zero or more nodes of the argument and outp (the <em>query argument</em>), selects zero or more nodes of the argument and ou
uts tputs
these nodes as a nodelist.</t> these nodes as a nodelist.</t>
<t>A query <bcp14>MUST</bcp14> be encoded using UTF-8. <t>A query <bcp14>MUST</bcp14> be encoded using UTF-8.
The grammar for queries given in this document assumes that its UTF-8 form is fi rst decoded into The grammar for queries given in this document assumes that its UTF-8 form is fi rst decoded into
Unicode scalar values as described Unicode scalar values as described
in <xref target="RFC3629"/>; implementation approaches that lead to an equivalen t in <xref target="RFC3629"/>; implementation approaches that lead to an equivalen t
result are possible.</t> result are possible.</t>
<t>A string to be used as a JSONPath query needs to be <em>well-formed</
em> and <t>A string to be used as a JSONPath query needs to be <em>well-formed</em> and
<em>valid</em>. <em>valid</em>.
A string is a well-formed JSONPath query if it conforms to the ABNF syntax in th is document. A string is a well-formed JSONPath query if it conforms to the ABNF syntax in th is document.
A well-formed JSONPath query is valid if it also fulfills all semantic A well-formed JSONPath query is valid if it also fulfills both semantic
requirements posed by this document, which are:</t> requirements posed by this document, which are as follows:</t>
<ol spacing="normal" type="1"><li>Integer numbers in the JSONPath query that are relevant <ol spacing="normal" type="1"><li>Integer numbers in the JSONPath query that are relevant
to the JSONPath processing (e.g., index values and steps) <bcp14>MUST</bcp14> be to the JSONPath processing (e.g., index values and steps) <bcp14>MUST</bcp14> be
within the range of exact integer values defined in I-JSON (see <xref section="2 within the range of exact integer values defined in Internet JSON (I-JSON) (see
.2" sectionFormat="of" target="RFC7493"/>), namely within the interval [−(2<sup> <xref section="2.2" sectionFormat="of" target="RFC7493"/>), namely within the in
53</sup>)+1, terval [-(2<sup>53</sup>)+1,
(2<sup>53</sup>)−1].</li> (2<sup>53</sup>)-1].</li>
<li>Uses of function extensions <bcp14>MUST</bcp14> be <em>well-typed< /em>, <li>Uses of function extensions <bcp14>MUST</bcp14> be <em>well-typed< /em>,
as described in <xref target="fnex"/>.</li> as described in <xref target="well-typedness"/>.</li>
</ol> </ol>
<t>A JSONPath implementation <bcp14>MUST</bcp14> raise an error for any query which is not <t>A JSONPath implementation <bcp14>MUST</bcp14> raise an error for any query that is not
well-formed and valid. well-formed and valid.
The well-formedness and the validity of JSONPath queries are independent of The well-formedness and the validity of JSONPath queries are independent of
the JSON value the query is applied to. No further errors relating to the the JSON value the query is applied to. No further errors relating to the
well-formedness and the validity of a JSONPath query can be well-formedness and the validity of a JSONPath query can be
raised during application of the query to a value. raised during application of the query to a value.
This clearly separates well-formedness/validity errors in the query This clearly separates well-formedness/validity errors in the query
from mismatches that may actually stem from flaws in the data.</t> from mismatches that may actually stem from flaws in the data.</t>
<t>Mismatches between the structure expected by a valid query <t>Mismatches between the structure expected by a valid query
and the structure found in the data can lead to empty query results, and the structure found in the data can lead to empty query results,
which may be unexpected and indicate bugs in either. which may be unexpected and indicate bugs in either.
JSONPath implementations might therefore want to provide diagnostics JSONPath implementations might therefore want to provide diagnostics
to the application developer that aid in finding the cause of empty to the application developer that aid in finding the cause of empty
results.</t> results.</t>
<t>Obviously, an implementation can still fail when executing a JSONPath <t>Obviously, an implementation can still fail when executing a JSONPath
query, e.g., because of resource depletion, but this is not modeled in query, e.g., because of resource depletion, but this is not modeled in
this document. However, the implementation <bcp14>MUST NOT</bcp14> this document. However, the implementation <bcp14>MUST NOT</bcp14>
silently malfunction. Specifically, if a valid JSONPath query is silently malfunction. Specifically, if a valid JSONPath query is
evaluated against a structured value whose size is too large to evaluated against a structured value whose size is too large to
process the query correctly (for instance requiring the processing of process the query correctly (for instance, requiring the processing of
numbers that fall outside the range of exact values), the implementation numbers that fall outside the range of exact values), the implementation
<bcp14>MUST</bcp14> provide an indication of overflow.</t> <bcp14>MUST</bcp14> provide an indication of overflow.</t>
<t>(Readers familiar with the HTTP error model may be reminded of 400 <t>(Readers familiar with the HTTP error model may be reminded of 400
type errors when pondering well-formedness and validity, while type errors when pondering well-formedness and validity, and they may
resource depletion and related errors are comparable to 500 type recognize resource depletion and related errors as comparable to 500 type
errors.)</t> errors.)</t>
<section anchor="syntax"> <section anchor="syntax">
<name>Syntax</name> <name>Syntax</name>
<t>Syntactically, a JSONPath query consists of a root identifier (<tt> $</tt>), which <t>Syntactically, a JSONPath query consists of a root identifier (<tt> $</tt>), which
stands for a nodelist that contains the root node of the query argument, stands for a nodelist that contains the root node of the query argument,
followed by a possibly empty sequence of <em>segments</em>.</t> followed by a possibly empty sequence of <em>segments</em>.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
jsonpath-query = root-identifier segments jsonpath-query = root-identifier segments
segments = *(S segment) segments = *(S segment)
skipping to change at line 648 skipping to change at line 624
%x0D ; Carriage return %x0D ; Carriage return
S = *B ; optional blank space S = *B ; optional blank space
]]></sourcecode> ]]></sourcecode>
<t>The syntax and semantics of segments are defined in <xref target="s egments-details"/>.</t> <t>The syntax and semantics of segments are defined in <xref target="s egments-details"/>.</t>
</section> </section>
<section anchor="semantics"> <section anchor="semantics">
<name>Semantics</name> <name>Semantics</name>
<t>In this document, the semantics of a JSONPath query define the <t>In this document, the semantics of a JSONPath query define the
required results and do not prescribe the internal workings of an required results and do not prescribe the internal workings of an
implementation. This document may describe semantics in a procedural implementation. This document may describe semantics in a procedural
step-by-step fashion, but such descriptions are normative only in the sense that step-by-step fashion; however, such descriptions are normative only in the sense
any implementation <bcp14>MUST</bcp14> produce an identical result, but not in that any implementation <bcp14>MUST</bcp14> produce an identical result but not
the sense that implementors are required to use the same algorithms.</t> in the sense that implementers are required to use the same algorithms.</t>
<t>The semantics are that a valid query is executed against a value, <t>The semantics are that a valid query is executed against a value
the <em>query argument</em>, and produces a nodelist (i.e., a list of zero or mo (the <em>query argument</em>) and produces a nodelist (i.e., a list of zero or m
re nodes of the value).</t> ore nodes of the value).</t>
<t>The query is a root identifier followed by a sequence of zero or mo re segments, each of <t>The query is a root identifier followed by a sequence of zero or mo re segments, each of
which is applied to the result of the previous root identifier or segment and pr ovides which is applied to the result of the previous root identifier or segment and pr ovides
input to the next segment. input to the next segment.
These results and inputs take the form of nodelists.</t> These results and inputs take the form of nodelists.</t>
<t>The nodelist resulting from the root identifier contains a single n <t>The nodelist resulting from the root identifier contains a single n
ode, ode
the query argument. (the query argument).
The nodelist resulting from the last segment is presented as the The nodelist resulting from the last segment is presented as the
result of the query. Depending on the specific API, it might be result of the query. Depending on the specific API, it might be
presented as an array of the JSON values at the nodes, an array of presented as an array of the JSON values at the nodes, an array of
Normalized Paths referencing the nodes, or both or some other Normalized Paths referencing the nodes, or both -- or some other
representation as desired by the implementation. representation as desired by the implementation.
Note: an empty nodelist is a valid query result.</t> Note: An empty nodelist is a valid query result.</t>
<t>A segment operates on each of the nodes in its input nodelist in tu rn, <t>A segment operates on each of the nodes in its input nodelist in tu rn,
and the resultant nodelists are concatenated in the order of the input and the resultant nodelists are concatenated in the order of the input
nodelist they were derived from to produce nodelist they were derived from to produce
the result of the segment. A node may be selected more than once and the result of the segment. A node may be selected more than once and
appears that number of times in the nodelist. Duplicate nodes are not removed.</ t> appears that number of times in the nodelist. Duplicate nodes are not removed.</ t>
<t>A syntactically valid segment <bcp14>MUST NOT</bcp14> produce error s when executing the query. <t>A syntactically valid segment <bcp14>MUST NOT</bcp14> produce error s when executing the query.
This means that some This means that some
operations that might be considered erroneous, such as using an index operations that might be considered erroneous, such as using an index
lying outside the range of an array, lying outside the range of an array,
simply result in fewer nodes being selected. simply result in fewer nodes being selected.
(Additional discussion of this property can be found in the (Additional discussion of this property can be found in the introduction of <xre
introduction to <xref target="synsem-overview"/>.)</t> f target="synsem-overview"/>.)</t>
<t>As a consequence of this approach, if any of the segments produces <t>As a consequence of this approach, if any of the segments
an empty nodelist, produces an empty nodelist, then the whole query produces an empty
then the whole query produces an empty nodelist.</t> nodelist.
<t>If a query may produce a nodelist with more than one possible order </t>
ing, a particular implementation <t>If the semantics of a query give an implementation a choice of prod
may also produce distinct orderings in successive runs of the query.</t> ucing multiple possible orderings, a particular implementation
may produce distinct orderings in successive runs of the query.</t>
</section> </section>
<section anchor="example"> <section anchor="example">
<name>Example</name> <name>Example</name>
<t>Consider this example. With the query argument <tt>{"a":[{"b":0},{" b":1},{"c":2}]}</tt>, the <t>Consider this example. With the query argument <tt>{"a":[{"b":0},{" b":1},{"c":2}]}</tt>, the
query <tt>$.a[*].b</tt> selects the following list of nodes: <tt>0</tt>, <tt>1</ query <tt>$.a[*].b</tt> selects the following list of nodes (denoted here by the
tt> ir values): <tt>0</tt>, <tt>1</tt>.</t>
(denoted here by their value).</t>
<t>The query consists of <tt>$</tt> followed by three segments: <tt>.a </tt>, <tt>[*]</tt>, and <tt>.b</tt>.</t> <t>The query consists of <tt>$</tt> followed by three segments: <tt>.a </tt>, <tt>[*]</tt>, and <tt>.b</tt>.</t>
<t>Firstly, <tt>$</tt> produces a nodelist consisting of just the quer y argument.</t> <t>First, <tt>$</tt> produces a nodelist consisting of just the query argument.</t>
<t>Next, <tt>.a</tt> selects from any object input node and selects th e <t>Next, <tt>.a</tt> selects from any object input node and selects th e
node of any node of any
member value of the input member value of the input
node corresponding to the member name <tt>"a"</tt>. node corresponding to the member name <tt>"a"</tt>.
The result is again a list of one node: <tt>[{"b":0},{"b":1},{"c":2}]</tt>.</t> The result is again a list containing a single node: <tt>[{"b":0},{"b":1},{"c":2
<t>Next, <tt>[*]</tt> selects from any array input node all its elemen }]</tt>.</t>
ts <t>Next, <tt>[*]</tt> selects all the elements
(for an object input node, it would select all its member from the input array node.
values, but not the member names).
The result is a list of three nodes: <tt>{"b":0}</tt>, <tt>{"b":1}</tt>, and <tt >{"c":2}</tt>.</t> The result is a list of three nodes: <tt>{"b":0}</tt>, <tt>{"b":1}</tt>, and <tt >{"c":2}</tt>.</t>
<t>Finally, <tt>.b</tt> selects from any object input node with a memb er name <t>Finally, <tt>.b</tt> selects from any object input node with a memb er name
<tt>b</tt> and selects the node of the member value of the input node correspond ing to that name. <tt>b</tt> and selects the node of the member value of the input node correspond ing to that name.
The result is a list containing <tt>0</tt>, <tt>1</tt>. The result is a list containing <tt>0</tt>, <tt>1</tt>.
This is the concatenation of three lists, two of length one containing This is the concatenation of three lists: two of length one containing
<tt>0</tt>, <tt>1</tt>, respectively, and one of length zero.</t> <tt>0</tt>, <tt>1</tt>, respectively, and one of length zero.</t>
</section> </section>
</section> </section>
<section anchor="root-identifier"> <section anchor="root-identifier">
<name>Root Identifier</name> <name>Root Identifier</name>
<section anchor="syntax-1"> <section anchor="syntax-1">
<name>Syntax</name> <name>Syntax</name>
<t>Every JSONPath query (except those inside filter expressions, see < xref target="filter-selector"/>) <bcp14>MUST</bcp14> begin with the root identif ier <tt>$</tt>.</t> <t>Every JSONPath query (except those inside filter expressions; see < xref target="filter-selector"/>) <bcp14>MUST</bcp14> begin with the root identif ier <tt>$</tt>.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
root-identifier = "$" root-identifier = "$"
]]></sourcecode> ]]></sourcecode>
</section> </section>
<section anchor="semantics-1"> <section anchor="semantics-1">
<name>Semantics</name> <name>Semantics</name>
<t>The root identifier <tt>$</tt> represents the root node of the quer y argument <t>The root identifier <tt>$</tt> represents the root node of the quer y argument
and produces a nodelist consisting of that root node.</t> and produces a nodelist consisting of that root node.</t>
</section> </section>
<section anchor="examples"> <section anchor="examples">
<name>Examples</name> <name>Examples</name>
<aside> <aside>
<t>In this and the following examples in Sections <xref format="coun <t>Note: In this example and the following examples in Sections <xre
ter" target="root-identifier"/> and f format="counter" target="root-identifier"/> and
<xref format="counter" target="selector-details"/> except for <xref target="tbl- <xref format="counter" target="selector-details"/>, except for <xref target="tbl
comparison"/>, we will present a -comparison"/>, we will present a
JSON text to show the JSON value used as the query argument to the JSON text to show the JSON value used as the query argument to the
queries in the examples, and then a table with the columns:</t> queries in the examples and then a table with the following columns:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>Query: an example query to be applied to the query argument</l i> <li>Query: an example query to be applied to the query argument</l i>
<li>Result: the query result as a list of JSON values that were lo cated in the query argument</li> <li>Result: the query result as a list of JSON values that were lo cated in the query argument</li>
<li>Result Path: the query result as a list of (normalized) paths into <li>Result Path: the query result as a list of (normalized) paths into
the query argument, giving locations of the JSON values in the previous column</ li> the query argument, giving locations of the JSON values in the previous column</ li>
<li>Comment: descriptive information</li> <li>Comment: descriptive information</li>
</ul> </ul>
</aside> </aside>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{"k": "v"} {"k": "v"}
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<table anchor="tbl-root"> <table anchor="tbl-root">
<name>Root identifier examples</name> <name>Root Identifier Example</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Path</th> <th align="center">Result Path</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 766 skipping to change at line 741
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="selector-details"> <section anchor="selector-details">
<name>Selectors</name> <name>Selectors</name>
<t>Selectors appear only inside <xref target="child-segment">child segme nts</xref> and <t>Selectors appear only inside <xref target="child-segment">child segme nts</xref> and
<xref target="descendant-segment">descendant segments</xref>.</t> <xref target="descendant-segment">descendant segments</xref>.</t>
<t>A selector produces a nodelist consisting of zero or more children of the input value.</t> <t>A selector produces a nodelist consisting of zero or more children of the input value.</t>
<t>There are various kinds of selectors which produce children of object s, children of arrays, <t>There are various kinds of selectors that produce children of objects , children of arrays,
or children of either objects or arrays.</t> or children of either objects or arrays.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
selector = name-selector / selector = name-selector /
wildcard-selector / wildcard-selector /
slice-selector / slice-selector /
index-selector / index-selector /
filter-selector filter-selector
]]></sourcecode> ]]></sourcecode>
<t>The syntax and semantics of each kind of selector are defined below.< /t> <t>The syntax and semantics of each kind of selector are defined below.< /t>
<section anchor="name-selector"> <section anchor="name-selector">
<name>Name Selector</name> <name>Name Selector</name>
<section anchor="syntax-name"> <section anchor="syntax-name">
<name>Syntax</name> <name>Syntax</name>
skipping to change at line 799 skipping to change at line 774
double-quoted = unescaped / double-quoted = unescaped /
%x27 / ; ' %x27 / ; '
ESC %x22 / ; \" ESC %x22 / ; \"
ESC escapable ESC escapable
single-quoted = unescaped / single-quoted = unescaped /
%x22 / ; " %x22 / ; "
ESC %x27 / ; \' ESC %x27 / ; \'
ESC escapable ESC escapable
ESC = %x5C ; \ backslash ESC = %x5C ; \ backslash
unescaped = %x20-21 / ; see RFC 8259 unescaped = %x20-21 / ; see RFC 8259
; omit 0x22 " ; omit 0x22 "
%x23-26 / %x23-26 /
; omit 0x27 ' ; omit 0x27 '
%x28-5B / %x28-5B /
; omit 0x5C \ ; omit 0x5C \
%x5D-D7FF / ; skip surrogate code points %x5D-D7FF /
; skip surrogate code points
%xE000-10FFFF %xE000-10FFFF
escapable = %x62 / ; b BS backspace U+0008 escapable = %x62 / ; b BS backspace U+0008
%x66 / ; f FF form feed U+000C %x66 / ; f FF form feed U+000C
%x6E / ; n LF line feed U+000A %x6E / ; n LF line feed U+000A
%x72 / ; r CR carriage return U+000D %x72 / ; r CR carriage return U+000D
%x74 / ; t HT horizontal tab U+0009 %x74 / ; t HT horizontal tab U+0009
"/" / ; / slash (solidus) U+002F "/" / ; / slash (solidus) U+002F
"\" / ; \ backslash (reverse solidus) U+005C "\" / ; \ backslash (reverse solidus) U+005C
(%x75 hexchar) ; uXXXX U+XXXX (%x75 hexchar) ; uXXXX U+XXXX
hexchar = non-surrogate / hexchar = non-surrogate /
(high-surrogate "\" %x75 low-surrogate) (high-surrogate "\" %x75 low-surrogate)
non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) /
("D" %x30-37 2HEXDIG ) ("D" %x30-37 2HEXDIG )
high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG
low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
]]></sourcecode> ]]></sourcecode>
<t>Notes:</t> <t>Notes:</t>
<ul spacing="normal"> <ul spacing="normal">
<li> <li>
<tt>double-quoted</tt> strings follow the JSON string syntax (<x <tt>Double-quoted</tt> strings follow the JSON string syntax (<x
ref section="7" sectionFormat="of" target="RFC8259"/>); ref section="7" sectionFormat="of" target="RFC8259"/>);
<tt>single-quoted</tt> strings follow an analogous pattern (<xref target="syntax <tt>single-quoted</tt> strings follow an analogous pattern.
-index"/>).
No attempt was made to improve on this syntax, so if it is desired to No attempt was made to improve on this syntax, so if it is desired to
escape characters with escape characters with
scalar values above 0xFFFF, such as <u format="num-lit-name">🤔</u>, scalar values above 0xFFFF, such as <u format="num-lit-name">🎼</u>,
they need to be represented they need to be represented
by a pair of surrogate escapes (<tt>"\uD83E\uDD14"</tt> in this case).</li> by a pair of surrogate escapes (<tt>"\uD83C\uDFBC"</tt> in this case).</li>
<li>Alphabetic characters in ABNF quoted strings are case-insensit <li>Alphabetic characters in quoted strings are case-insensitive i
ive, n ABNF,
so each of the hexadecimal digits within <tt>\u</tt> escapes (as specified in ru les so each of the hexadecimal digits within <tt>\u</tt> escapes (as specified in ru les
referenced by <tt>hexchar</tt>) can be either lower case or upper case, referenced by <tt>hexchar</tt>) can be either lowercase or uppercase,
while the <tt>u</tt> in <tt>\u</tt> needs to be lower case (indicated as <tt>%x7 while the <tt>u</tt> in <tt>\u</tt> needs to be lowercase (indicated as <tt>%x75
5</tt>).</li> </tt>).</li>
</ul> </ul>
</section> </section>
<section anchor="semantics-2"> <section anchor="semantics-2">
<name>Semantics</name> <name>Semantics</name>
<t>A <tt>name-selector</tt> string <bcp14>MUST</bcp14> be converted to a <t>A <tt>name-selector</tt> string <bcp14>MUST</bcp14> be converted to a
member name <tt>M</tt> by removing the surrounding quotes and member name <tt>M</tt> by removing the surrounding quotes and
replacing each escape sequence with its equivalent Unicode character, as replacing each escape sequence with its equivalent Unicode character, as
shown in <xref target="tbl-esc"/>:</t> shown in <xref target="tbl-esc"/>:</t>
<table anchor="tbl-esc"> <table anchor="tbl-esc">
<name>Escape Sequence Replacements</name> <name>Escape Sequence Replacements</name>
skipping to change at line 923 skipping to change at line 899
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>\uXXXX</tt></td> <tt>\uXXXX</tt></td>
<td align="center">see <xref target="syntax-name"/></td> <td align="center">see <xref target="syntax-name"/></td>
<td align="left">hexadecimal escape</td> <td align="left">hexadecimal escape</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<t>Applying the <tt>name-selector</tt> to an object node <t>Applying the <tt>name-selector</tt> to an object node
selects a member value whose name equals the member name <tt>M</tt>, selects a member value whose name equals the member name <tt>M</tt>
or selects nothing if there is no such member value. or selects nothing if there is no such member value.
Nothing is selected from a value that is not an object.</t> Nothing is selected from a value that is not an object.</t>
<t>Note: processing the name selector requires comparing the member name string <tt>M</tt> <t>Note: Processing the name selector requires comparing the member name string <tt>M</tt>
with member name strings in the JSON to which the selector is being applied. with member name strings in the JSON to which the selector is being applied.
Two strings <bcp14>MUST</bcp14> be considered equal if and only if they are iden tical Two strings <bcp14>MUST</bcp14> be considered equal if and only if they are iden tical
sequences of Unicode scalar values. In other words, normalization operations sequences of Unicode scalar values. In other words, normalization operations
<bcp14>MUST NOT</bcp14> be applied to either the member name string <tt>M</tt> f rom the JSONPath or to <bcp14>MUST NOT</bcp14> be applied to either the member name string <tt>M</tt> f rom the JSONPath or
the member name strings in the JSON prior to comparison.</t> the member name strings in the JSON prior to comparison.</t>
</section> </section>
<section anchor="examples-1"> <section anchor="examples-1">
<name>Examples</name> <name>Examples</name>
<!-- EDITING NOTE: there are non-breaking spaces here between j and
j -->
<!-- i.e., j j and not j j -->
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{ {
"o": {"j j": {"k.k": 3}}, "o": {"j j": {"k.k": 3}},
"'": {"@": 2} "'": {"@": 2}
} }
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<t>The examples in <xref target="tbl-name"/> show the name selector in use by child segments:</t> <t>The examples in <xref target="tbl-name"/> show the name selector in use by child segments.</t>
<table anchor="tbl-name"> <table anchor="tbl-name">
<name>Name selector examples</name> <name>Name Selector Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.o['j j']</tt></td> <tt>$.o['j j']</tt></td>
<td align="left"> <td align="left">
<tt>{"k.k": 3}</tt></td> <tt>{"k.k": 3}</tt></td>
<td align="center"> <td align="center">
<tt>$['o']['j j']</tt></td> <tt>$['o']['j j']</tt></td>
<td align="left">Named value in nested object</td> <td align="left">Named <br/>value in <br/>a nested <br/>object
</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.o['j j']['k.k']</tt></td> <tt>$.o['j&nbsp;j']&wj;['k.k']</tt></td>
<td align="left"> <td align="left">
<tt>3</tt></td> <tt>3</tt></td>
<td align="center"> <td align="center">
<tt>$['o']['j j']['k.k']</tt></td> <tt>$['o']['j&nbsp;j']&wj;['k.k']</tt></td>
<td align="left">Nesting further down</td> <td align="left">Nesting <br/>further <br/>down</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.o["j j"]["k.k"]</tt></td> <tt>$.o["j&nbsp;j"]&wj;["k.k"]</tt></td>
<td align="left"> <td align="left">
<tt>3</tt></td> <tt>3</tt></td>
<td align="center"> <td align="center">
<tt>$['o']['j j']['k.k']</tt></td> <tt>$['o']['j&nbsp;j']&wj;['k.k']</tt></td>
<td align="left">Different delimiter in query, unchanged norma <td align="left">Different <br/>delimiter <br/>in the query, <
lized path</td> br/>unchanged <br/>Normalized <br/>Path</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$["'"]["@"]</tt></td> <tt>$["'"]["@"]</tt></td>
<td align="left"> <td align="left">
<tt>2</tt></td> <tt>2</tt></td>
<td align="center"> <td align="center">
<tt>$['\'']['@']</tt></td> <tt>$['\'']['@']</tt></td>
<td align="left">Unusual member names</td> <td align="left">Unusual <br/>member <br/>names</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="wildcard-selector"> <section anchor="wildcard-selector">
<name>Wildcard Selector</name> <name>Wildcard Selector</name>
<section anchor="syntax-2"> <section anchor="syntax-2">
<name>Syntax</name> <name>Syntax</name>
<t>The wildcard selector consists of an asterisk.</t> <t>The wildcard selector consists of an asterisk.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
wildcard-selector = "*" wildcard-selector = "*"
]]></sourcecode> ]]></sourcecode>
</section> </section>
<section anchor="semantics-3"> <section anchor="semantics-3">
<name>Semantics</name> <name>Semantics</name>
<t>A wildcard selector selects the nodes of all children of an objec t or array. <t>A wildcard selector selects the nodes of all children of an objec t or array.
The order in which the children of an object appear in the resultant nodelist is not stipulated, The order in which the children of an object appear in the resultant nodelist is not stipulated,
since JSON objects are unordered. since JSON objects are unordered.
Children of an array appear in array order in the resultant nodelist.</t> Children of an array appear in array order in the resultant nodelist.
</t>
<t>Note that the children of an object are its member values, not its
member names.</t>
<t>The wildcard selector selects nothing from a primitive JSON value (that is, <t>The wildcard selector selects nothing from a primitive JSON value (that is,
a number, a string, <tt>true</tt>, <tt>false</tt>, or <tt>null</tt>).</t> a number, a string, <tt>true</tt>, <tt>false</tt>, or <tt>null</tt>).</t>
</section> </section>
<section anchor="examples-2"> <section anchor="examples-2">
<name>Examples</name> <name>Examples</name>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{ {
"o": {"j": 1, "k": 2}, "o": {"j": 1, "k": 2},
"a": [5, 3] "a": [5, 3]
} }
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<t>The examples in <xref target="tbl-wild"/> show the wildcard selec tor in use by a child segment:</t> <t>The examples in <xref target="tbl-wild"/> show the wildcard selec tor in use by a child segment.</t>
<table anchor="tbl-wild"> <table anchor="tbl-wild">
<name>Wildcard selector examples</name> <name>Wildcard Selector Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 1086 skipping to change at line 1060
<tt>$.a[*]</tt></td> <tt>$.a[*]</tt></td>
<td align="left"> <td align="left">
<tt>5</tt> <br/> <tt>3</tt></td> <tt>5</tt> <br/> <tt>3</tt></td>
<td align="center"> <td align="center">
<tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt></td> <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt></td>
<td align="left">Array members</td> <td align="left">Array members</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<t>The example above with the query <tt>$.o[*, *]</tt> shows that th e wildcard selector may produce nodelists in distinct <t>The example above with the query <tt>$.o[*, *]</tt> shows that th e wildcard selector may produce nodelists in distinct
orders each time it appears in the child segment, when it is applied to an objec t node with two or more orders each time it 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 fewer than two members or to array nodes).</t> members (but not when it is applied to object nodes with fewer than two members or to array nodes).</t>
</section> </section>
</section> </section>
<section anchor="index-selector"> <section anchor="index-selector">
<name>Index Selector</name> <name>Index Selector</name>
<section anchor="syntax-index"> <section anchor="syntax-index">
<name>Syntax</name> <name>Syntax</name>
<t>An index selector <tt>&lt;index&gt;</tt> matches at most one arra y element value.</t> <t>An index selector <tt>&lt;index&gt;</tt> matches at most one arra y element value.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
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
]]></sourcecode> ]]></sourcecode>
<t>Applying the numerical <tt>index-selector</tt> selects the corres ponding <t>Applying the numerical <tt>index-selector</tt> selects the corres ponding
element. JSONPath allows it to be negative (see <xref target="index-semantics"/> ).</t> element. JSONPath allows it to be negative (see <xref target="index-semantics"/> ).</t>
<t>To be valid, the index selector value <bcp14>MUST</bcp14> be in t he I-JSON <t>To be valid, the index selector value <bcp14>MUST</bcp14> be in t he I-JSON
range of exact values, see <xref target="synsem-overview"/>.</t> range of exact values (see <xref target="synsem-overview"/>).</t>
<t>Notes:</t> <t>Notes:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>An <tt>index-selector</tt> is an integer (in base 10, as in JS ON numbers).</li> <li>An <tt>index-selector</tt> is an integer (in base 10, as in JS ON numbers).</li>
<li>As in JSON numbers, the syntax does not allow octal-like integ ers with leading zeros such as <tt>01</tt> or <tt>-01</tt>.</li> <li>As in JSON numbers, the syntax does not allow octal-like integ ers with leading zeros, such as <tt>01</tt> or <tt>-01</tt>.</li>
</ul> </ul>
</section> </section>
<section anchor="index-semantics"> <section anchor="index-semantics">
<name>Semantics</name> <name>Semantics</name>
<t>A non-negative <tt>index-selector</tt> applied to an array select s an array element using a zero-based index. <t>A non-negative <tt>index-selector</tt> applied to an array select s an array element using a zero-based index.
For example, the selector <tt>0</tt> selects the first and the selector <tt>4</t t> selects the fifth element of a sufficiently long array. For example, the selector <tt>0</tt> selects the first, and the selector <tt>4</ tt> selects the fifth element of a sufficiently long array.
Nothing is selected, and it is not an error, if the index lies outside the range of the array. Nothing is selected from a value that is not an array.</t> Nothing is selected, and it is not an error, if the index lies outside the range of the array. Nothing is selected from a value that is not an array.</t>
<t>A negative <tt>index-selector</tt> counts from the array end back wards, <t>A negative <tt>index-selector</tt> counts from the array end back wards,
obtaining an equivalent non-negative <tt>index-selector</tt> by summing the obtaining an equivalent non-negative <tt>index-selector</tt> by adding the
length of the array with the negative index. length of the array to the negative index.
For example, the selector <tt>-1</tt> selects the last and the selector <tt>-2</ For example, the selector <tt>-1</tt> selects the last, and the selector <tt>-2<
tt> selects the penultimate element of an array with at least two elements. /tt> selects the 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 As with non-negative indexes, it is not an error if such an element does
not exist; this simply means that no element is selected.</t> not exist; this simply means that no element is selected.</t>
</section> </section>
<section anchor="examples-3"> <section anchor="examples-3">
<name>Examples</name> <name>Examples</name>
<!-- EDITING NOTE: there are non-breaking spaces here between j and
j -->
<!-- i.e., j j and not j j -->
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
["a","b"] ["a","b"]
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<t>The examples in <xref target="tbl-index"/> show the index selecto r in use by a child segment.</t> <t>The examples in <xref target="tbl-index"/> show the index selecto r in use by a child segment.</t>
<table anchor="tbl-index"> <table anchor="tbl-index">
<name>Index selector examples</name> <name>Index Selector Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 1169 skipping to change at line 1140
<tt>"a"</tt></td> <tt>"a"</tt></td>
<td align="center"> <td align="center">
<tt>$[0]</tt></td> <tt>$[0]</tt></td>
<td align="left">Element of array, from the end</td> <td align="left">Element of array, from the end</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="slice"> <section anchor="slice">
<name>Array Slice selector</name> <name>Array Slice Selector</name>
<section anchor="syntax-3"> <section anchor="syntax-3">
<name>Syntax</name> <name>Syntax</name>
<t>The array slice selector has the form <tt>&lt;start&gt;:&lt;end&g t;:&lt;step&gt;</tt>. <t>The array slice selector has the form <tt>&lt;start&gt;:&lt;end&g t;:&lt;step&gt;</tt>.
It matches elements from arrays starting at index <tt>&lt;start&gt;</tt>, ending It matches elements from arrays starting at index <tt>&lt;start&gt;</tt> and end
at — but ing at (but
not including — <tt>&lt;end&gt;</tt>, while incrementing by <tt>step</tt> with a not including) <tt>&lt;end&gt;</tt>, while incrementing by <tt>step</tt> with a
default of <tt>1</tt>.</t> default of <tt>1</tt>.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
slice-selector = [start S] ":" S [end S] [":" [S step ]] slice-selector = [start S] ":" S [end S] [":" [S step ]]
start = int ; included in selection start = int ; included in selection
end = int ; not included in selection end = int ; not included in selection
step = int ; default: 1 step = int ; default: 1
]]></sourcecode> ]]></sourcecode>
<t>The slice selector consists of three optional decimal integers se parated by colons. <t>The slice selector consists of three optional decimal integers se parated by colons.
The second colon can be omitted when the third integer is.</t> The second colon can be omitted when the third integer is omitted.</t>
<t>To be valid, the integers provided <bcp14>MUST</bcp14> be in the I-JSON <t>To be valid, the integers provided <bcp14>MUST</bcp14> be in the I-JSON
range of exact values, see <xref target="synsem-overview"/>.</t> range of exact values (see <xref target="synsem-overview"/>).</t>
</section> </section>
<section anchor="semantics-4"> <section anchor="semantics-4">
<name>Semantics</name> <name>Semantics</name>
<t>The slice selector was inspired by the slice operator of ECMAScri <t>The slice selector was inspired by
pt the slice operator that was proposed for ECMAScript 4 (ES4), whic
4 (ES4), which was deprecated in 2014, and that of Python.</t> h was never released,
and that of Python.</t>
<section anchor="informal-introduction"> <section anchor="informal-introduction">
<name>Informal Introduction</name> <name>Informal Introduction</name>
<t>This section is informative.</t> <t>This section is informative.</t>
<t>Array slicing is inspired by the behavior of the <tt>Array.prot otype.slice</tt> method <t>Array slicing is inspired by the behavior of the <tt>Array.prot otype.slice</tt> method
of the JavaScript language as defined by the ECMA-262 standard <xref target="ECM A-262"/>, of the JavaScript language, as defined by the ECMA-262 standard <xref target="EC MA-262"/>,
with the addition of the <tt>step</tt> parameter, which is inspired by the Pytho n slice expression.</t> with the addition of the <tt>step</tt> parameter, which is inspired by the Pytho n slice expression.</t>
<t>The array slice expression <tt>start:end:step</tt> selects elem ents at indices starting at <tt>start</tt>, <t>The array slice expression <tt>start:end:step</tt> selects elem ents at indices starting at <tt>start</tt>,
incrementing by <tt>step</tt>, and ending with <tt>end</tt> (which is itself exc luded). incrementing by <tt>step</tt>, and ending with <tt>end</tt> (which is itself exc luded).
So, for example, the expression <tt>1:3</tt> (where <tt>step</tt> defaults to <t t>1</tt>) So, for example, the expression <tt>1:3</tt> (where <tt>step</tt> defaults to <t t>1</tt>)
selects elements with indices <tt>1</tt> and <tt>2</tt> (in that order) whereas selects elements with indices <tt>1</tt> and <tt>2</tt> (in that order), whereas
<tt>1:5:2</tt> selects elements with indices <tt>1</tt> and <tt>3</tt>.</t> <tt>1:5:2</tt> selects elements with indices <tt>1</tt> and <tt>3</tt>.</t>
<t>When <tt>step</tt> is negative, elements are selected in revers e order. Thus, <t>When <tt>step</tt> is negative, elements are selected in revers e order. Thus,
for example, <tt>5:1:-2</tt> selects elements with indices <tt>5</tt> and <tt>3< for example, <tt>5:1:-2</tt> selects elements with indices <tt>5</tt> and <tt>3<
/tt>, in /tt> (in
that order and <tt>::-1</tt> selects all the elements of an array in that order), and <tt>::-1</tt> selects all the elements of an array in
reverse order.</t> reverse order.</t>
<t>When <tt>step</tt> is <tt>0</tt>, no elements are selected. <t>When <tt>step</tt> is <tt>0</tt>, no elements are selected.
(This is the one case that differs from the behavior of Python, which (This is the one case that differs from the behavior of Python, which
raises an error in this case.)</t> raises an error in this case.)</t>
<t>The following section specifies the behavior fully, without dep ending on <t>The following section specifies the behavior fully, without dep ending on
JavaScript or Python behavior.</t> JavaScript or Python behavior.</t>
</section> </section>
<section anchor="normative-semantics"> <section anchor="normative-semantics">
<name>Normative Semantics</name> <name>Normative Semantics</name>
<t>A slice expression selects a subset of the elements of the inpu t array, in <t>A slice expression selects a subset of the elements of the inpu t array in
the same order the same order
as the array or the reverse order, depending on the sign of the <tt>step</tt> pa rameter. as the array or the reverse order, depending on the sign of the <tt>step</tt> pa rameter.
It selects no nodes from a node that is not an array.</t> It selects no nodes from a node that is not an array.</t>
<t>A slice is defined by the two slice parameters, <tt>start</tt> and <tt>end</tt>, and <t>A slice is defined by the two slice parameters, <tt>start</tt> and <tt>end</tt>, and
an iteration delta, <tt>step</tt>. an iteration delta, <tt>step</tt>.
Each of these parameters is Each of these parameters is
optional. In the rest of this section, <tt>len</tt> denotes the length of the in put array.</t> optional. In the rest of this section, <tt>len</tt> denotes the length of the in put array.</t>
<t>The default value for <tt>step</tt> is <tt>1</tt>. <t>The default value for <tt>step</tt> is <tt>1</tt>.
The default values for <tt>start</tt> and <tt>end</tt> depend on the sign of <tt >step</tt>, The default values for <tt>start</tt> and <tt>end</tt> depend on the sign of <tt >step</tt>,
as shown in <xref target="tbl-slice-start-end"/>:</t> as shown in <xref target="tbl-slice-start-end"/>.</t>
<table anchor="tbl-slice-start-end"> <table anchor="tbl-slice-start-end">
<name>Default array slice start and end values</name> <name>Default Array Slice start and end Values</name>
<thead> <thead>
<tr> <tr>
<th align="left">Condition</th> <th align="left">Condition</th>
<th align="left">start</th> <th align="left">start</th>
<th align="left">end</th> <th align="left">end</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left">step &gt;= 0</td> <td align="left">step &gt;= 0</td>
skipping to change at line 1303 skipping to change at line 1275
ELSE if step < 0 THEN ELSE if step < 0 THEN
i = upper i = upper
WHILE lower < i: WHILE lower < i:
SELECT a(i) SELECT a(i)
i = i + step i = i + step
END WHILE END WHILE
END IF END IF
]]></sourcecode> ]]></sourcecode>
<t>When <tt>step = 0</tt>, no elements are selected and the result array is empty.</t> <t>When <tt>step = 0</tt>, no elements are selected, and the resul t array is empty.</t>
</section> </section>
</section> </section>
<section anchor="examples-4"> <section anchor="examples-4">
<name>Examples</name> <name>Examples</name>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
["a", "b", "c", "d", "e", "f", "g"] ["a", "b", "c", "d", "e", "f", "g"]
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<t>The examples in <xref target="tbl-slice"/> show the array slice s elector in use by a child segment:</t> <t>The examples in <xref target="tbl-slice"/> show the array slice s elector in use by a child segment.</t>
<table anchor="tbl-slice"> <table anchor="tbl-slice">
<name>Array slice selector examples</name> <name>Array Slice Selector Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 1375 skipping to change at line 1347
<tt>"g"</tt> <br/> <tt>"f"</tt> <br/> <tt>"e"</tt> <br/> <tt >"d"</tt> <br/> <tt>"c"</tt> <br/> <tt>"b"</tt> <br/> <tt>"a"</tt></td> <tt>"g"</tt> <br/> <tt>"f"</tt> <br/> <tt>"e"</tt> <br/> <tt >"d"</tt> <br/> <tt>"c"</tt> <br/> <tt>"b"</tt> <br/> <tt>"a"</tt></td>
<td align="center"> <td align="center">
<tt>$[6]</tt> <br/> <tt>$[5]</tt> <br/> <tt>$[4]</tt> <br/> <tt>$[3]</tt> <br/> <tt>$[2]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[0]</tt></td> <tt>$[6]</tt> <br/> <tt>$[5]</tt> <br/> <tt>$[4]</tt> <br/> <tt>$[3]</tt> <br/> <tt>$[2]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[0]</tt></td>
<td align="left">Slice in reverse order</td> <td align="left">Slice in reverse order</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="filter-selector"> <section anchor="filter-selector">
<name>Filter selector</name> <name>Filter Selector</name>
<t>Filter selectors are used to iterate over the elements or members o f <t>Filter selectors are used to iterate over the elements or members o f
structured values, i.e., JSON arrays and objects. structured values, i.e., JSON arrays and objects.
The structured values are identified in the nodelist offered by the The structured values are identified in the nodelist offered by the
child or descendant segment using the filter selector.</t> child or descendant segment using the filter selector.</t>
<t>For each iteration (element/member), a logical expression, the <em> <t>For each iteration (element/member), a logical expression (the <em>
filter expression</em>, filter expression</em>)
is evaluated which decides whether the node of is evaluated, which decides whether the node of
the element/member is selected. the element/member is selected.
(While a logical expression evaluates to what mathematically is a (While a logical expression evaluates to what mathematically is a
Boolean value, this specification uses the term <em>logical</em> to maintain a d istinction from Boolean value, this specification uses the term <em>logical</em> to maintain a d istinction from
the Boolean values that JSON can represent.)</t> the Boolean values that JSON can represent.)</t>
<t>During the iteration process, the filter expression receives the no de <t>During the iteration process, the filter expression receives the no de
of each array element or object member value of the structured value being of each array element or object member value of the structured value being
filtered; this element or member value is then known as the <em>current node</em >.</t> filtered; this element or member value is then known as the <em>current node</em >.</t>
<t>The current node can be used as the start of one or more JSONPath <t>The current node can be used as the start of one or more JSONPath
queries in subexpressions of the filter expression, notated queries in subexpressions of the filter expression, notated
via the current-node-identifier <tt>@</tt>. via the current-node-identifier <tt>@</tt>.
Each JSONPath query can be used either for testing existence of a Each JSONPath query can be used either for testing existence of a
result of the query, for obtaining a specific JSON value resulting result of the query, for obtaining a specific JSON value resulting
from that query that can then be used in a comparison, or as a from that query that can then be used in a comparison, or as a
<em>function argument</em>.</t> <em>function argument</em>.</t>
<t>Filter selectors may use function extensions, which are covered in <xref target="fnex"/>. <t>Filter selectors may use function extensions, which are covered in <xref target="fnex"/>.
Within the logical expression for a filter selector, function Within the logical expression for a filter selector, function
expressions can be used to operate on nodelists and values. expressions can be used to operate on nodelists and values.
The set of available functions is extensible, with a number of The set of available functions is extensible, with a number of
functions predefined, see <xref target="fnex"/>, and the ability to register fur functions predefined (see <xref target="fnex"/>) and the ability to register fur
ther ther
functions provided by the Function Extensions sub-registry (<xref target="iana-f functions provided by the "Function Extensions" subregistry (<xref target="iana-
nex"/>). fnex"/>).
When a function is defined, it is given a unique name, and its return value and When a function is defined, it is given a unique name, and its return value and
each of its parameters is given a each of its parameters are given a
<em>declared type</em>. <em>declared type</em>.
The type system is limited in scope; its purpose is to express The type system is limited in scope; its purpose is to express
restrictions that, without functions, are implicit in the grammar of restrictions that, without functions, are implicit in the grammar of
filter expressions. filter expressions.
The type system also guides conversions (<xref target="type-conv"/>) that mimic the The type system also guides conversions (<xref target="type-conv"/>) that mimic the
way different kinds of expressions are handled in the grammar when way different kinds of expressions are handled in the grammar when
function expressions are not in use.</t> function expressions are not in use.</t>
<section anchor="filter-selector-syntax"> <section anchor="filter-selector-syntax">
<name>Syntax</name> <name>Syntax</name>
<t>The filter selector has the form <tt>?&lt;logical-expr&gt;</tt>.< /t> <t>The filter selector has the form <tt>?&lt;logical-expr&gt;</tt>.< /t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
filter-selector = "?" S logical-expr filter-selector = "?" S logical-expr
]]></sourcecode> ]]></sourcecode>
<t>As the filter expression is composed of side-effect free constitu ents, <t>As the filter expression is composed of constituents free of side effects,
the order of evaluation does not need to be (and is not) defined. the order of evaluation does not need to be (and is not) defined.
Similarly, for conjunction (<tt>&amp;&amp;</tt>) and disjunction (<tt>||</tt>) ( defined later), Similarly, for conjunction (<tt>&amp;&amp;</tt>) and disjunction (<tt>||</tt>) ( defined later),
both a short-circuiting and a fully evaluating both a short-circuiting and a fully evaluating
implementation will lead to the same result; both implementation implementation will lead to the same result; both implementation
strategies are therefore valid.</t> strategies are therefore valid.</t>
<t>The current node is accessible via the current node identifier <t t>@</tt>. <t>The current node is accessible via the current node identifier <t t>@</tt>.
This identifier addresses the current node of the filter-selector that This identifier addresses the current node of the filter-selector that
is directly enclosing the identifier. Note: within nested is directly enclosing the identifier. Note: Within nested
filter-selectors, there is no syntax to address the current node of filter-selectors, there is no syntax to address the current node of
any other than the directly enclosing filter-selector (i.e., of any other than the directly enclosing filter-selector (i.e., of
filter-selectors enclosing the filter-selector that is directly filter-selectors enclosing the filter-selector that is directly
enclosing the identifier).</t> enclosing the identifier).</t>
<t>Logical expressions offer the usual Boolean operators (<tt>||</tt > for OR, <t>Logical expressions offer the usual Boolean operators (<tt>||</tt > for OR,
<tt>&amp;&amp;</tt> for AND, and <tt>!</tt> for NOT). <tt>&amp;&amp;</tt> for AND, and <tt>!</tt> for NOT).
They have the normal semantics of Boolean algebra and obey its laws They have the normal semantics of Boolean algebra and obey its laws
(see, for example, <xref target="BOOLEAN-LAWS"/>). (for example, see <xref target="BOOLEAN-LAWS"/>).
Parentheses <bcp14>MAY</bcp14> be used within <tt>logical-expr</tt> for grouping .</t> Parentheses <bcp14>MAY</bcp14> be used within <tt>logical-expr</tt> for grouping .</t>
<t>It is not required that <tt>logical-expr</tt> consist of <t>It is not required that <tt>logical-expr</tt> consist of
a parenthesized expression (which was required in <xref target="JSONPath-orig"/> ), a parenthesized expression (which was required in <xref target="JSONPath-orig"/> ),
although it can be, and the semantics are the same although it can be, and the semantics are the same
as without the parentheses.</t> as without the parentheses.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
logical-expr = logical-or-expr logical-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
skipping to change at line 1467 skipping to change at line 1439
designated by an embedded query (see <xref target="extest"/>) or tests the designated by an embedded query (see <xref target="extest"/>) or tests the
result of a function expression (see <xref target="fnex"/>). result of a function expression (see <xref target="fnex"/>).
In the latter case, if the function's declared result type is In the latter case, if the function's declared result type is
<tt>LogicalType</tt> (see <xref target="typesys"/>), it tests whether the result <tt>LogicalType</tt> (see <xref target="typesys"/>), it tests whether the result
is <tt>LogicalTrue</tt>; if the function's declared result type is is <tt>LogicalTrue</tt>; if the function's declared result type is
<tt>NodesType</tt>, it tests whether the result is non-empty. <tt>NodesType</tt>, it tests whether the result is non-empty.
If the function's declared result type is <tt>ValueType</tt>, its use in a If the function's declared result type is <tt>ValueType</tt>, its use in a
test expression is not well-typed (see <xref target="well-typedness"/>).</t> test expression is not well-typed (see <xref target="well-typedness"/>).</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
test-expr = [logical-not-op S] test-expr = [logical-not-op S]
(filter-query / ; existence/non-existence (filter-query / ; existence/non-existence
function-expr) ; LogicalType or NodesType function-expr) ; LogicalType or NodesType
filter-query = rel-query / jsonpath-query filter-query = rel-query / jsonpath-query
rel-query = current-node-identifier segments rel-query = current-node-identifier segments
current-node-identifier = "@" current-node-identifier = "@"
]]></sourcecode> ]]></sourcecode>
<t>Comparison expressions are available for comparisons between prim itive <t>Comparison expressions are available for comparisons between prim itive
values (that is, numbers, strings, <tt>true</tt>, <tt>false</tt>, and <tt>null</ tt>). values (that is, numbers, strings, <tt>true</tt>, <tt>false</tt>, and <tt>null</ tt>).
These can be obtained via literal values; singular queries, each of These can be obtained via literal values; singular queries, each of
which selects at most one node the value of which is then used; or which selects at most one node, the value of which is then used; or
function expressions (see <xref target="fnex"/>) of type <tt>ValueType</tt>.</t> function expressions (see <xref target="fnex"/>) of type <tt>ValueType</tt>.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
comparison-expr = comparable S comparison-op S comparable comparison-expr = comparable S comparison-op S comparable
literal = number / string-literal / literal = number / string-literal /
true / false / null true / false / null
comparable = literal / comparable = literal /
singular-query / ; singular query value singular-query / ; singular query value
function-expr ; ValueType function-expr ; ValueType
comparison-op = "==" / "!=" / comparison-op = "==" / "!=" /
"<=" / ">=" / "<=" / ">=" /
skipping to change at line 1499 skipping to change at line 1471
singular-query = rel-singular-query / abs-singular-query singular-query = rel-singular-query / abs-singular-query
rel-singular-query = current-node-identifier singular-query-segments rel-singular-query = current-node-identifier singular-query-segments
abs-singular-query = root-identifier singular-query-segments abs-singular-query = root-identifier singular-query-segments
singular-query-segments = *(S (name-segment / index-segment)) singular-query-segments = *(S (name-segment / index-segment))
name-segment = ("[" name-selector "]") / name-segment = ("[" name-selector "]") /
("." member-name-shorthand) ("." member-name-shorthand)
index-segment = "[" index-selector "]" index-segment = "[" index-selector "]"
]]></sourcecode> ]]></sourcecode>
<t>Literals can be notated in the way that is usual for JSON (with t he <t>Literals can be notated in the way that is usual for JSON (with t he
extension that strings can use single-quote delimiters).</t> extension that strings can use single-quote delimiters).</t>
<t>Note: Alphabetic characters in ABNF quoted strings are case-insen <t>Note: Alphabetic characters in quoted strings are case-insensitiv
sitive, so within a e in ABNF, so within a
floating point number the ABNF expression "e" can be either the character floating point number, the ABNF expression "e" can be either the character
'e' or 'E'.</t> 'e' or 'E'.</t>
<t><tt>true</tt>, <tt>false</tt>, and <tt>null</tt> are lower-case o nly (case-sensitive).</t> <t><tt>true</tt>, <tt>false</tt>, and <tt>null</tt> are lowercase on ly (case-sensitive).</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
number = (int / "-0") [ frac ] [ exp ] ; decimal number number = (int / "-0") [ 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
]]></sourcecode> ]]></sourcecode>
<t><xref target="tbl-prec"/> lists filter expression operators in or der of precedence from highest (binds most tightly) to lowest (binds least tight ly).</t> <t><xref target="tbl-prec"/> lists filter expression operators in or der of precedence from highest (binds most tightly) to lowest (binds least tight ly).</t>
<!-- FIXME: Should the syntax column be split between unary and bina
ry operators? -->
<table anchor="tbl-prec"> <table anchor="tbl-prec">
<name>Filter expression operator precedence</name> <name>Filter Expression Operator Precedence</name>
<thead> <thead>
<tr> <tr>
<th align="center">Precedence</th> <th align="center">Precedence</th>
<th align="center">Operator type</th> <th align="center">Operator type</th>
<th align="center">Syntax</th> <th align="center">Syntax</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="center">5</td> <td align="center">5</td>
skipping to change at line 1540 skipping to change at line 1510
<tr> <tr>
<td align="center">4</td> <td align="center">4</td>
<td align="center">Logical NOT</td> <td align="center">Logical NOT</td>
<td align="center"> <td align="center">
<tt>!</tt></td> <tt>!</tt></td>
</tr> </tr>
<tr> <tr>
<td align="center">3</td> <td align="center">3</td>
<td align="center">Relations</td> <td align="center">Relations</td>
<td align="center"> <td align="center">
<tt>==</tt> <tt>!=</tt><br/><tt>&lt;</tt> <tt>&lt;=</tt> <tt >&gt;</tt> <tt>&gt;=</tt></td> <tt>==</tt> <tt>!=</tt><br/><tt>&lt;</tt> <tt>&lt;=</tt> <tt >&gt;</tt> <tt>&gt;=</tt></td>
</tr> </tr>
<tr> <tr>
<td align="center">2</td> <td align="center">2</td>
<td align="center">Logical AND</td> <td align="center">Logical AND</td>
<td align="center"> <td align="center">
<tt>&amp;&amp;</tt></td> <tt>&amp;&amp;</tt></td>
</tr> </tr>
<tr> <tr>
<td align="center">1</td> <td align="center">1</td>
<td align="center">Logical OR</td> <td align="center">Logical OR</td>
<td align="center"> <td align="center">
<tt>||</tt></td> <tt>||</tt></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
<section anchor="semantics-5"> <section anchor="semantics-5">
<name>Semantics</name> <name>Semantics</name>
<t>The filter selector works with arrays and objects exclusively. It s result is a list of <em>zero</em>, <em>one</em>, <em>multiple</em> or <em>all< /em> of their array elements or member values, respectively. <t>The filter selector works with arrays and objects exclusively. It s result is a list of (<em>zero</em>, <em>one</em>, <em>multiple</em>, or <em>al l</em>) their array elements or member values, respectively.
Applied to a primitive value, it selects nothing (and therefore does Applied to a primitive value, it selects nothing (and therefore does
not contribute to the result of the filter selector).</t> not contribute to the result of the filter selector).</t>
<t>In the resultant nodelist, children of an array are ordered by th eir position in the array. <t>In the resultant nodelist, children of an array are ordered by th eir position in the array.
The order in which the children of an object (as opposed to an array) The order in which the children of an object (as opposed to an array)
appear in the resultant nodelist is not stipulated, appear in the resultant nodelist is not stipulated,
since JSON objects are unordered.</t> since JSON objects are unordered.</t>
<section anchor="extest"> <section anchor="extest">
<name>Existence Tests</name> <name>Existence Tests</name>
<t>A query by itself in a logical context is an existence test whi ch yields true if the query selects at least one node and yields false if the qu ery does not select any nodes.</t> <t>A query by itself in a logical context is an existence test tha t yields true if the query selects at least one node and yields false if the que ry does not select any nodes.</t>
<t>Existence tests differ from comparisons in that:</t> <t>Existence tests differ from comparisons in that:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>they work with arbitrary relative or absolute queries (not j <li>They work with arbitrary relative or absolute queries (not j
ust singular queries).</li> ust singular queries).</li>
<li>they work with queries that select structured values.</li> <li>They work with queries that select structured values.</li>
</ul> </ul>
<t>To examine the value of a node selected by a query, an explicit comparison is necessary. <t>To examine the value of a node selected by a query, an explicit comparison is necessary.
For example, to test whether the node selected by the query <tt>@.foo</tt> has t he value <tt>null</tt>, use <tt>@.foo == null</tt> (see <xref target="null-seman tics"/>) For example, to test whether the node selected by the query <tt>@.foo</tt> has t he value <tt>null</tt>, use <tt>@.foo == null</tt> (see <xref target="null-seman tics"/>)
rather than the negated existence test <tt>!@.foo</tt> (which yields false if <t t>@.foo</tt> selects a node, regardless of the node's value). rather than the negated existence test <tt>!@.foo</tt> (which yields false if <t t>@.foo</tt> selects a node, regardless of the node's value).
Similarly, <tt>@.foo == false</tt> yields true only if <tt>@.foo</tt> selects a node and Similarly, <tt>@.foo == false</tt> yields true only if <tt>@.foo</tt> selects a node and
the value of that node is <tt>false</tt>.</t> the value of that node is <tt>false</tt>.</t>
</section> </section>
<section anchor="comparisons"> <section anchor="comparisons">
<name>Comparisons</name> <name>Comparisons</name>
<t>The comparison operators <tt>==</tt> and <tt>&lt;</tt> are defi ned first and then these are used to define <tt>!=</tt>, <tt>&lt;=</tt>, <tt>&gt ;</tt>, and <tt>&gt;=</tt>.</t> <t>The comparison operators <tt>==</tt> and <tt>&lt;</tt> are defi ned first, and then these are used to define <tt>!=</tt>, <tt>&lt;=</tt>, <tt>&g t;</tt>, and <tt>&gt;=</tt>.</t>
<t>When either side of a comparison results in an empty nodelist o r the <t>When either side of a comparison results in an empty nodelist o r the
special result <tt>Nothing</tt> (see <xref target="typesys"/>):</t> special result <tt>Nothing</tt> (see <xref target="typesys"/>):</t>
<ul spacing="normal"> <ul spacing="normal">
<li>a comparison using the operator <tt>==</tt> yields true if a nd only the <li>A comparison using the operator <tt>==</tt> yields true if a nd only the
other side also results in an empty nodelist or the special result <tt>Nothing</ tt>.</li> other side also results in an empty nodelist or the special result <tt>Nothing</ tt>.</li>
<li>a comparison using the operator <tt>&lt;</tt> yields false.< /li> <li>A comparison using the operator <tt>&lt;</tt> yields false.< /li>
</ul> </ul>
<t>When any query or function expression on either side of a compa rison results in a nodelist consisting of a single node, that side is <t>When any query or function expression on either side of a compa rison results in a nodelist consisting of a single node, that side is
replaced by the value of its node and then:</t> replaced by the value of its node and then:</t>
<ul spacing="normal"> <ul spacing="normal">
<li> <li>
<t>a comparison using the operator <tt>==</tt> yields true if and only if the comparison <t>A comparison using the operator <tt>==</tt> yields true if and only if the comparison
is between: is between:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li>numbers expected to interoperate as per <xref section="2 <li>numbers expected to interoperate, as per <xref section="
.2" sectionFormat="of" target="RFC7493">I-JSON</xref> that compare equal using n 2.2" sectionFormat="of" target="RFC7493">I-JSON</xref>, that compare equal using
ormal mathematical equality,</li> normal mathematical equality,</li>
<li>numbers at least one of which is not expected to interop <li>numbers, at least one of which is not expected to intero
erate as per I-JSON, where the numbers compare equal using an implementation spe perate as per I-JSON, where the numbers compare equal using an implementation-sp
cific equality,</li> ecific equality,</li>
<li>equal primitive values which are not numbers,</li> <li>equal primitive values that are not numbers,</li>
<li>equal arrays, that is arrays of the same length where ea <li>equal arrays, that is, arrays of the same length where e
ch element of the first array is equal to the corresponding ach element of the first array is equal to the corresponding
element of the second array, or</li> element of the second array, or</li>
<li> <li>
<t>equal objects with no duplicate names, that is where: <t>equal objects with no duplicate names, that is, where:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li>both objects have the same collection of names (with no duplicates), and</li> <li>both objects have the same collection of names (with no duplicates) and</li>
<li>for each of those names, the values associated with the name by the objects are equal.</li> <li>for each of those names, the values associated with the name by the objects are equal.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
<li> <li>
<t>a comparison using the operator <tt>&lt;</tt> yields true i <t>A comparison using the operator <tt>&lt;</tt> yields true i
f and only if f and only if
the comparison is between values which are both numbers or both strings and whic the comparison is between values that are both numbers or both strings and that
h satisfy the comparison: </t> satisfy the comparison: </t>
<ul spacing="normal"> <ul spacing="normal">
<li>numbers expected to interoperate as per <xref section="2 <li>numbers expected to interoperate, as per <xref section="
.2" sectionFormat="of" target="RFC7493">I-JSON</xref> <bcp14>MUST</bcp14> compar 2.2" sectionFormat="of" target="RFC7493">I-JSON</xref>, <bcp14>MUST</bcp14> comp
e using the normal mathematical ordering; are using the normal mathematical ordering;
numbers not expected to interoperate as per I-JSON <bcp14>MAY</bcp14> compare us numbers not expected to interoperate, as per I-JSON, <bcp14>MAY</bcp14> compare
ing an implementation specific ordering</li> using an implementation-specific ordering,</li>
<li>the empty string compares less than any non-empty string <li>the empty string compares less than any non-empty string
</li> , and</li>
<li>a non-empty string compares less than another non-empty string if and only if the first string starts with a <li>a non-empty string compares less than another non-empty string if and only if the first string starts with a
lower Unicode scalar value than the second string or if both strings start with the same Unicode scalar value and lower Unicode scalar value than the second string or if both strings start with the same Unicode scalar value and
the remainder of the first string compares less than the remainder of the second string.</li> the remainder of the first string compares less than the remainder of the second string.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<t><tt>!=</tt>, <tt>&lt;=</tt>, <tt>&gt;</tt>, and <tt>&gt;=</tt> are defined in terms of the other comparison operators. For any <tt>a</tt> and < tt>b</tt>:</t> <t><tt>!=</tt>, <tt>&lt;=</tt>, <tt>&gt;</tt>, and <tt>&gt;=</tt> are defined in terms of the other comparison operators. For any <tt>a</tt> and < tt>b</tt>:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>The comparison <tt>a != b</tt> yields true if and only if <t t>a == b</tt> yields false.</li> <li>The comparison <tt>a != b</tt> yields true if and only if <t t>a == b</tt> yields false.</li>
<li>The comparison <tt>a &lt;= b</tt> yields true if and only if <tt>a &lt; b</tt> yields true or <tt>a == b</tt> yields true.</li> <li>The comparison <tt>a &lt;= b</tt> yields true if and only if <tt>a &lt; b</tt> yields true or <tt>a == b</tt> yields true.</li>
skipping to change at line 1648 skipping to change at line 1618
result with a given JSON value as input.</t> result with a given JSON value as input.</t>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{ {
"obj": {"x": "y"}, "obj": {"x": "y"},
"arr": [2, 3] "arr": [2, 3]
} }
]]></sourcecode> ]]></sourcecode>
<t>Comparisons:</t> <t>Comparisons:</t>
<table anchor="tbl-comparison"> <table anchor="tbl-comparison">
<name>Comparison examples</name> <name>Comparison Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Comparison</th> <th align="center">Comparison</th>
<th align="center">Result</th> <th align="center">Result</th>
<th align="center">Comment</th> <th align="center">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="center"> <td align="center">
skipping to change at line 1698 skipping to change at line 1668
<tr> <tr>
<td align="center"> <td align="center">
<tt>1 &lt;= 2</tt></td> <tt>1 &lt;= 2</tt></td>
<td align="center">true</td> <td align="center">true</td>
<td align="center">Numeric comparison</td> <td align="center">Numeric comparison</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>1 &gt; 2</tt></td> <tt>1 &gt; 2</tt></td>
<td align="center">false</td> <td align="center">false</td>
<td align="center">Strict, numeric comparison</td> <td align="center">Numeric comparison</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>13 == '13'</tt></td> <tt>13 == '13'</tt></td>
<td align="center">false</td> <td align="center">false</td>
<td align="center">Type mismatch</td> <td align="center">Type mismatch</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>'a' &lt;= 'b'</tt></td> <tt>'a' &lt;= 'b'</tt></td>
<td align="center">true</td> <td align="center">true</td>
<td align="center">String comparison</td> <td align="center">String comparison</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>'a' &gt; 'b'</tt></td> <tt>'a' &gt; 'b'</tt></td>
<td align="center">false</td> <td align="center">false</td>
<td align="center">Strict, string comparison</td> <td align="center">String comparison</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.obj == $.arr</tt></td> <tt>$.obj == $.arr</tt></td>
<td align="center">false</td> <td align="center">false</td>
<td align="center">Type mismatch</td> <td align="center">Type mismatch</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.obj != $.arr</tt></td> <tt>$.obj != $.arr</tt></td>
skipping to change at line 1832 skipping to change at line 1802
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>true &gt; true</tt></td> <tt>true &gt; true</tt></td>
<td align="center">false</td> <td align="center">false</td>
<td align="center">Booleans do not offer <tt>&lt;</tt> compari son</td> <td align="center">Booleans do not offer <tt>&lt;</tt> compari son</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<t>The second set of examples shows some complete JSONPath queries t hat make use <t>The second set of examples shows some complete JSONPath queries t hat make use
of filter selectors, and the results of evaluating these queries on a of filter selectors and the results of evaluating these queries on a
given JSON value as input. given JSON value as input.
(Note: two of the queries employ function extensions; please see (Note: Two of the queries employ function extensions; please see
Sections <xref format="counter" target="match"/> and <xref format="counter" targ Sections <xref format="counter" target="match"/> and <xref format="counter" targ
et="search"/> below for details about these.)</t> et="search"/> for details about these.)</t>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{ {
"a": [3, 5, 1, 2, 4, 6, "a": [3, 5, 1, 2, 4, 6,
{"b": "j"}, {"b": "j"},
{"b": "k"}, {"b": "k"},
{"b": {}}, {"b": {}},
{"b": "kilo"} {"b": "kilo"}
], ],
"o": {"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}}, "o": {"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}},
"e": "f" "e": "f"
} }
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<t>The examples in <xref target="tbl-filter"/> show the filter selec tor in use by a child segment:</t> <t>The examples in <xref target="tbl-filter"/> show the filter selec tor in use by a child segment.</t>
<table anchor="tbl-filter"> <table anchor="tbl-filter">
<name>Filter selector examples</name> <name>Filter Selector Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 2009 skipping to change at line 1979
<t>The example above with the query <tt>$.o[?@&lt;3, ?@&lt;3]</tt> s hows that a filter selector may produce nodelists in distinct <t>The example above with the query <tt>$.o[?@&lt;3, ?@&lt;3]</tt> s hows that a filter selector may produce nodelists in distinct
orders each time it appears in the child segment.</t> orders each time it appears in the child segment.</t>
</section> </section>
</section> </section>
</section> </section>
<section anchor="fnex"> <section anchor="fnex">
<name>Function Extensions</name> <name>Function Extensions</name>
<t>Beyond the filter expression functionality defined in the preceding <t>Beyond the filter expression functionality defined in the preceding
subsections, JSONPath defines an extension point that can be used to subsections, JSONPath defines an extension point that can be used to
add filter expression functionality: "Function Extensions".</t> add filter expression functionality: "Function Extensions".</t>
<t>This section defines the extension point as well as some function <t>This section defines the extension point and some function
extensions that use this extension point. extensions that use this extension point.
While these mechanisms are designed to use the extension point, While these mechanisms are designed to use the extension point,
they are an integral part of the JSONPath specification and are they are an integral part of the JSONPath specification and are
expected to be implemented like any other integral part of this expected to be implemented like any other integral part of this
specification.</t> specification.</t>
<t>A function extension defines a registered name (see <xref target="ian a-fnex"/>) that <t>A function extension defines a registered name (see <xref target="ian a-fnex"/>) that
can be applied to a sequence of zero or more arguments, producing a can be applied to a sequence of zero or more arguments, producing a
result. Each registered function name is unique.</t> result. Each registered function name is unique.</t>
<t>A function extension <bcp14>MUST</bcp14> be defined such that its eva luation is <t>A function extension <bcp14>MUST</bcp14> be defined such that its eva luation is
side-effect free, i.e., all possible orders of evaluation and choices free of side effects, i.e., all possible orders of evaluation and choices
of short-circuiting or full evaluation of an expression containing it of short-circuiting or full evaluation of an expression containing it
<bcp14>MUST</bcp14> lead to the same result. <bcp14>MUST</bcp14> lead to the same result.
(Note: memoization or logging are not side effects in this sense (Note: Memoization or logging are not side effects in this sense
as they are visible at the implementation level only they do not as they are visible at the implementation level only -- they do not
influence the result of the evaluation.)</t> influence the result of the evaluation.)</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
function-name = function-name-first *function-name-char function-name = function-name-first *function-name-char
function-name-first = LCALPHA function-name-first = LCALPHA
function-name-char = function-name-first / "_" / DIGIT function-name-char = function-name-first / "_" / DIGIT
LCALPHA = %x61-7A ; "a".."z" LCALPHA = %x61-7A ; "a".."z"
function-expr = function-name "(" S [function-argument function-expr = function-name "(" S [function-argument
*(S "," S function-argument)] S ")" *(S "," S function-argument)] S ")"
function-argument = literal / function-argument = literal /
filter-query / ; (includes singular-query) filter-query / ; (includes singular-query)
logical-expr / logical-expr /
function-expr function-expr
]]></sourcecode> ]]></sourcecode>
<t>Any function expressions in a query must be well-formed (by conformin g to the above ABNF) <t>Any function expressions in a query must be well-formed (by conformin g to the above ABNF)
and well-typed, and well-typed;
otherwise the JSONPath implementation <bcp14>MUST</bcp14> raise an error otherwise, the JSONPath implementation <bcp14>MUST</bcp14> raise an error
(see <xref target="synsem-overview"/>). (see <xref target="synsem-overview"/>).
To define which function expressions are well-typed, To define which function expressions are well-typed,
a type system is first introduced.</t> a type system is first introduced.</t>
<section anchor="typesys"> <section anchor="typesys">
<name>Type System for Function Expressions</name> <name>Type System for Function Expressions</name>
<t>Each parameter as well as the result of a function extension must h ave a declared type.</t> <t>Each parameter and the result of a function extension must have a d eclared type.</t>
<t>Declared types enable checking a JSONPath query for well-typedness <t>Declared types enable checking a JSONPath query for well-typedness
independent of any query argument the JSONPath query is applied to.</t> independent of any query argument the JSONPath query is applied to.</t>
<t><xref target="tbl-types"/> defines the available types in terms of the instances they contain.</t> <t><xref target="tbl-types"/> defines the available types in terms of the instances they contain.</t>
<table anchor="tbl-types"> <table anchor="tbl-types">
<name>Function extension type system</name> <name>Function Extension Type System</name>
<thead> <thead>
<tr> <tr>
<th align="left">Type</th> <th align="left">Type</th>
<th align="left">Instances</th> <th align="left">Instances</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left"> <td align="left">
<tt>ValueType</tt></td> <tt>ValueType</tt></td>
skipping to change at line 2114 skipping to change at line 2084
<tt>ValueType</tt> by wrapping the expression in a call to a function extension, <tt>ValueType</tt> by wrapping the expression in a call to a function extension,
such as <tt>value()</tt> (see <xref target="value"/>), such as <tt>value()</tt> (see <xref target="value"/>),
that takes a parameter of type <tt>NodesType</tt> and returns a that takes a parameter of type <tt>NodesType</tt> and returns a
result of type <tt>ValueType</tt>.</li> result of type <tt>ValueType</tt>.</li>
</ul> </ul>
<t>The well-typedness of function expressions can now be defined in te rms of this type system.</t> <t>The well-typedness of function expressions can now be defined in te rms of this type system.</t>
</section> </section>
<section anchor="well-typedness"> <section anchor="well-typedness">
<name>Well-Typedness of Function Expressions</name> <name>Well-Typedness of Function Expressions</name>
<t>For a function expression to be well-typed:</t> <t>For a function expression to be well-typed:</t>
<ol spacing="normal" type="1"><li>its declared type must be well-typed <ol spacing="normal" type="1">
in the context in which it occurs, and</li> <li><t>Its declared type must be well-typed in the context in which i
<li>its arguments must be well-typed for the declared type of the co t occurs.</t>
rresponding parameters.</li> <t>As per the grammar, a function expression can occur in three different
</ol>
<t>(1) As per the grammar, a function expression can occur in three di
fferent
immediate contexts, which lead to the following conditions for well-typedness:</ t> immediate contexts, which lead to the following conditions for well-typedness:</ t>
<dl newline="true"> <dl newline="true">
<dt>As a <tt>test-expr</tt> in a logical expression:</dt> <dt>As a <tt>test-expr</tt> in a logical expression:</dt>
<dd> <dd>
<t>The function's declared result type is <tt>LogicalType</tt>, or <t>The function's declared result type is <tt>LogicalType</tt> or
(giving rise to conversion as per <xref target="type-conv"/>) <tt>NodesType</tt> .</t> (giving rise to conversion as per <xref target="type-conv"/>) <tt>NodesType</tt> .</t>
</dd> </dd>
<dt>As a <tt>comparable</tt> in a comparison:</dt> <dt>As a <tt>comparable</tt> in a comparison:</dt>
<dd> <dd>
<t>The function's declared result type is <tt>ValueType</tt>.</t> <t>The function's declared result type is <tt>ValueType</tt>.</t>
</dd> </dd>
<dt>As a <tt>function-argument</tt> in another function expression:< /dt> <dt>As a <tt>function-argument</tt> in another function expression:< /dt>
<dd> <dd>
<t>The function's declared result type fulfills the following rule s for <t>The function's declared result type fulfills the following rule s for
the corresponding parameter of the enclosing function.</t> the corresponding parameter of the enclosing function.</t>
</dd> </dd>
</dl> </dl>
<t>(2) The arguments of the function expression are well-typed when </li>
<li><t>Its arguments must be well-typed for the declared type of the
corresponding parameters.</t>
<t>The arguments of the function expression are well-typed when
each argument of the function can be used for the declared type of the each argument of the function can be used for the declared type of the
corresponding parameter, according to one of the following corresponding parameter, according to one of the following
conditions:</t> conditions:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>When the argument is a function expression with declared result type the same as the <li>When the argument is a function expression with the same declare d result type as the
declared type of the parameter.</li> declared type of the parameter.</li>
<li> <li>
<t>When the declared type of the parameter is <tt>LogicalType</tt> and the argument is one of the following: <t>When the declared type of the parameter is <tt>LogicalType</tt> and the argument is one of the following:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li>A function expression with declared result type <tt>NodesTyp e</tt>. <li>A function expression with declared result type <tt>NodesTyp e</tt>.
In this case the argument is converted to LogicalType as per <xref target="type- conv"/>.</li> In this case, the argument is converted to LogicalType as per <xref target="type -conv"/>.</li>
<li>A <tt>logical-expr</tt> that is not a function expression.</ li> <li>A <tt>logical-expr</tt> that is not a function expression.</ li>
</ul> </ul>
</li> </li>
<li>When the declared type of the parameter is <tt>NodesType</tt> an d the argument is a query <li>When the declared type of the parameter is <tt>NodesType</tt> an d the argument is a query
(which includes singular query).</li> (which includes singular query).</li>
<li> <li>
<t>When the declared type of the parameter is <tt>ValueType</tt> a nd the argument is one of the following: <t>When the declared type of the parameter is <tt>ValueType</tt> a nd the argument is one of the following:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li>A value expressed as a literal.</li> <li>A value expressed as a literal.</li>
skipping to change at line 2169 skipping to change at line 2140
<t>A singular query. In this case: <t>A singular query. In this case:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li>If the query results in a nodelist consisting of a singl e node, the <li>If the query results in a nodelist consisting of a singl e node, the
argument is the value of the node.</li> argument is the value of the node.</li>
<li>If the query results in an empty nodelist, the argument is <li>If the query results in an empty nodelist, the argument is
the special result <tt>Nothing</tt>.</li> the special result <tt>Nothing</tt>.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li> </li>
</ul> </ul>
</li>
</ol>
</section> </section>
<section anchor="length"> <section anchor="length">
<name><tt>length()</tt> Function Extension</name> <name><tt>length()</tt> Function Extension</name>
<dl> <dl>
<dt>Parameters:</dt> <dt>Parameters:</dt>
<dd> <dd>
<ol spacing="normal" type="1"><li> <ol spacing="normal" type="1"><li>
<tt>ValueType</tt></li> <tt>ValueType</tt></li>
</ol> </ol>
</dd> </dd>
<dt>Result:</dt> <dt>Result:</dt>
<dd> <dd>
<t><tt>ValueType</tt> (unsigned integer or <tt>Nothing</tt>)</t> <t><tt>ValueType</tt> (unsigned integer or <tt>Nothing</tt>)</t>
</dd> </dd>
</dl> </dl>
<t>The <tt>length()</tt> function extension provides a way to compute the length <t>The <tt>length()</tt> function extension provides a way to compute the length
of a value and make that available for further processing in the of a value and make that available for further processing in the
filter expression:</t> filter expression:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$[?length(@.authors) >= 5] $[?length(@.authors) >= 5]
]]></sourcecode> ]]></sourcecode>
<t>Its only argument is an instance of <tt>ValueType</tt> (possibly ta ken from a <t>Its only argument is an instance of <tt>ValueType</tt> (possibly ta ken from a
singular query, as in the example above). The result also is an singular query, as in the example above). The result is also an
instance of <tt>ValueType</tt>: an unsigned integer or the special result <tt>No thing</tt>.</t> instance of <tt>ValueType</tt>: an unsigned integer or the special result <tt>No thing</tt>.</t>
<ul spacing="normal"> <ul spacing="normal">
<li>If the argument value is a string, the result is the number of <li>If the argument value is a string, the result is the number of
Unicode scalar values in the string.</li> Unicode scalar values in the string.</li>
<li>If the argument value is an array, the result is the number of <li>If the argument value is an array, the result is the number of
elements in the array.</li> elements in the array.</li>
<li>If the argument value is an object, the result is the number of <li>If the argument value is an object, the result is the number of
members in the object.</li> members in the object.</li>
<li>For any other argument value, the result is the special result < tt>Nothing</tt>.</li> <li>For any other argument value, the result is the special result < tt>Nothing</tt>.</li>
</ul> </ul>
skipping to change at line 2222 skipping to change at line 2195
</ol> </ol>
</dd> </dd>
<dt>Result:</dt> <dt>Result:</dt>
<dd> <dd>
<t><tt>ValueType</tt> (unsigned integer)</t> <t><tt>ValueType</tt> (unsigned integer)</t>
</dd> </dd>
</dl> </dl>
<t>The <tt>count()</tt> function extension provides a way to obtain th e number of <t>The <tt>count()</tt> function extension provides a way to obtain th e number of
nodes in a nodelist and make that available for further processing in nodes in a nodelist and make that available for further processing in
the filter expression:</t> the filter expression:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$[?count(@.*.author) >= 5] $[?count(@.*.author) >= 5]
]]></sourcecode> ]]></sourcecode>
<t>Its only argument is a nodelist. <t>Its only argument is a nodelist.
The result is a value, an unsigned integer, that gives the number of The result is a value (an unsigned integer) that gives the number of
nodes in the nodelist. nodes in the nodelist.</t>
Notes:</t> <t>Notes:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>There is no deduplication of the nodelist.</li> <li>There is no deduplication of the nodelist.</li>
<li>The number of nodes in the nodelist is counted independent of th eir <li>The number of nodes in the nodelist is counted independent of th eir
values or any children they may have; e.g., the count of a non-empty values or any children they may have, e.g., the count of a non-empty
singular nodelist such as <tt>count(@)</tt> is always 1.</li> singular nodelist such as <tt>count(@)</tt> is always 1.</li>
</ul> </ul>
</section> </section>
<section anchor="match"> <section anchor="match">
<name><tt>match()</tt> Function Extension</name> <name><tt>match()</tt> Function Extension</name>
<dl> <dl>
<dt>Parameters:</dt> <dt>Parameters:</dt>
<dd> <dd>
<ol spacing="normal" type="1"><li> <ol spacing="normal" type="1"><li>
<tt>ValueType</tt> (string)</li> <tt>ValueType</tt> (string)</li>
<li> <li>
<tt>ValueType</tt> (string conforming to <xref target="I-D.dra ft-ietf-jsonpath-iregexp"/>)</li> <tt>ValueType</tt> (string conforming to <xref target="RFC9485 "/>)</li>
</ol> </ol>
</dd> </dd>
<dt>Result:</dt> <dt>Result:</dt>
<dd> <dd>
<t><tt>LogicalType</tt></t> <t><tt>LogicalType</tt></t>
</dd> </dd>
</dl> </dl>
<t>The <tt>match()</tt> function extension provides a way to check whe ther (the <t>The <tt>match()</tt> function extension provides a way to check whe ther (the
entirety of, see <xref target="search"/> below) a given entirety of; see <xref target="search"/>) a given
string matches a given regular expression, which is in <xref target="I-D.draft-i string matches a given regular expression, which is in the form described in <xr
etf-jsonpath-iregexp"/> form.</t> ef target="RFC9485"/>.</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$[?match(@.date, "1974-05-..")] $[?match(@.date, "1974-05-..")]
]]></sourcecode> ]]></sourcecode>
<t>Its arguments are instances of <tt>ValueType</tt> (possibly taken f rom a <t>Its arguments are instances of <tt>ValueType</tt> (possibly taken f rom a
singular query, as for the first argument in the example above). singular query, as for the first argument in the example above).
If the first argument is not a string or the second argument is not a If the first argument is not a string or the second argument is not a
string conforming to <xref target="I-D.draft-ietf-jsonpath-iregexp"/>, the resul t is <tt>LogicalFalse</tt>. string conforming to <xref target="RFC9485"/>, the result is <tt>LogicalFalse</t t>.
Otherwise, the string that is the first argument is matched against Otherwise, the string that is the first argument is matched against
the iregexp contained in the string that is the second argument; the I-Regexp contained in the string that is the second argument;
the result is <tt>LogicalTrue</tt> if the string matches the iregexp and the result is <tt>LogicalTrue</tt> if the string matches the I-Regexp and is
<tt>LogicalFalse</tt> otherwise.</t> <tt>LogicalFalse</tt> otherwise.</t>
</section> </section>
<section anchor="search"> <section anchor="search">
<name><tt>search()</tt> Function Extension</name> <name><tt>search()</tt> Function Extension</name>
<dl> <dl>
<dt>Parameters:</dt> <dt>Parameters:</dt>
<dd> <dd>
<ol spacing="normal" type="1"><li> <ol spacing="normal" type="1"><li>
<tt>ValueType</tt> (string)</li> <tt>ValueType</tt> (string)</li>
<li> <li>
<tt>ValueType</tt> (string conforming to <xref target="I-D.dra ft-ietf-jsonpath-iregexp"/>)</li> <tt>ValueType</tt> (string conforming to <xref target="RFC9485 "/>)</li>
</ol> </ol>
</dd> </dd>
<dt>Result:</dt> <dt>Result:</dt>
<dd> <dd>
<t><tt>LogicalType</tt></t> <t><tt>LogicalType</tt></t>
</dd> </dd>
</dl> </dl>
<t>The <tt>search()</tt> function extension provides a way to check wh ether a <t>The <tt>search()</tt> function extension provides a way to check wh ether a
given string contains a substring that matches a given regular given string contains a substring that matches a given regular
expression, which is in <xref target="I-D.draft-ietf-jsonpath-iregexp"/> form.</ expression, which is in the form described in <xref target="RFC9485"/>.</t>
t> <sourcecode type="application/jsonpath"><![CDATA[
<sourcecode type="JSONPath"><![CDATA[
$[?search(@.author, "[BR]ob")] $[?search(@.author, "[BR]ob")]
]]></sourcecode> ]]></sourcecode>
<t>Its arguments are instances of <tt>ValueType</tt> (possibly taken f rom a <t>Its arguments are instances of <tt>ValueType</tt> (possibly taken f rom a
singular query, as for the first argument in the example above). singular query, as for the first argument in the example above).
If the first argument is not a string or the second argument is not a If the first argument is not a string or the second argument is not a
string conforming to <xref target="I-D.draft-ietf-jsonpath-iregexp"/>, the resul string conforming to <xref target="RFC9485"/>, the result is <tt>LogicalFalse</t
t is <tt>LogicalFalse</tt>. t>.
Otherwise, the string that is the first argument is searched for at Otherwise, the string that is the first argument is searched for a
least one substring that matches the iregexp contained in the string substring that matches the I-Regexp contained in the string
that is the second argument; the result is <tt>LogicalTrue</tt> if such a that is the second argument; the result is <tt>LogicalTrue</tt> if at
substring exists and <tt>LogicalFalse</tt> otherwise.</t> least one such substring exists and is <tt>LogicalFalse</tt> otherwise.</t>
</section> </section>
<section anchor="value"> <section anchor="value">
<name><tt>value()</tt> Function Extension</name> <name><tt>value()</tt> Function Extension</name>
<dl> <dl>
<dt>Parameters:</dt> <dt>Parameters:</dt>
<dd> <dd>
<ol spacing="normal" type="1"><li> <ol spacing="normal" type="1"><li>
<tt>NodesType</tt></li> <tt>NodesType</tt></li>
</ol> </ol>
</dd> </dd>
<dt>Result:</dt> <dt>Result:</dt>
<dd> <dd>
<t><tt>ValueType</tt></t> <t><tt>ValueType</tt></t>
</dd> </dd>
</dl> </dl>
<t>The <tt>value()</tt> function extension provides a way to convert a n instance of <tt>NodesType</tt> to a value and <t>The <tt>value()</tt> function extension provides a way to convert a n instance of <tt>NodesType</tt> to a value and
make that available for further processing in the filter expression:</t> make that available for further processing in the filter expression:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$[?value(@..color) == "red"] $[?value(@..color) == "red"]
]]></sourcecode> ]]></sourcecode>
<t>Its only argument is an instance of <tt>NodesType</tt> (possibly ta ken from a <t>Its only argument is an instance of <tt>NodesType</tt> (possibly ta ken from a
<tt>filter-query</tt>, as in the example above). The result is an <tt>filter-query</tt>, as in the example above). The result is an
instance of <tt>ValueType</tt>.</t> instance of <tt>ValueType</tt>.</t>
<ul spacing="normal"> <ul spacing="normal">
<li>If the argument contains a single node, the result is <li>If the argument contains a single node, the result is
the value of the node.</li> the value of the node.</li>
<li>If the argument is the special result <tt>Nothing</tt> or contai ns multiple nodes, the <li>If the argument is the empty nodelist or contains multiple nodes , the
result is <tt>Nothing</tt>.</li> result is <tt>Nothing</tt>.</li>
</ul> </ul>
<t>Note: a singular query may be used anywhere where a ValueType is ex pected, <t>Note: A singular query may be used anywhere where a ValueType is ex pected,
so there is no need to use the <tt>value()</tt> function extension with a singul ar query.</t> so there is no need to use the <tt>value()</tt> function extension with a singul ar query.</t>
</section> </section>
<section anchor="examples-6"> <section anchor="examples-6">
<name>Examples</name> <name>Examples</name>
<table anchor="tbl-function-expr"> <table anchor="tbl-function-expr">
<name>Function expression examples</name> <name>Function Expression Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$[?length(@) &lt; 3]</tt></td> <tt>$[?length(@) &lt; 3]</tt></td>
skipping to change at line 2429 skipping to change at line 2402
concatenated in the order of the input nodelist to form a single concatenated in the order of the input nodelist to form a single
segment result nodelist.</t> segment result nodelist.</t>
<t>It turns out that the more segments there are in a query, the greater the depth in the input value of the <t>It turns out that the more segments there are in a query, the greater the depth in the input value of the
nodes of the resultant nodelist:</t> nodes of the resultant nodelist:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>A query with N segments, where N &gt;= 0, produces a nodelist <li>A query with N segments, where N &gt;= 0, produces a nodelist
consisting of nodes at depth in the input value of N or greater.</li> consisting of nodes at depth in the input value of N or greater.</li>
<li>A query with N segments, where N &gt;= 0, all of which are <xref t arget="child-segment">child segments</xref>, <li>A query with N segments, where N &gt;= 0, all of which are <xref t arget="child-segment">child segments</xref>,
produces a nodelist consisting of nodes precisely at depth N in the input value. </li> produces a nodelist consisting of nodes precisely at depth N in the input value. </li>
</ul> </ul>
<t>There are two kinds of segment: child segments and descendant segment s.</t> <t>There are two kinds of segments: child segments and descendant segmen ts.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
segment = child-segment / descendant-segment segment = child-segment / descendant-segment
]]></sourcecode> ]]></sourcecode>
<t>The syntax and semantics of each kind of segment are defined below.</ t> <t>The syntax and semantics of each kind of segment are defined below.</ t>
<section anchor="child-segment"> <section anchor="child-segment">
<name>Child Segment</name> <name>Child Segment</name>
<section anchor="syntax-4"> <section anchor="syntax-4">
<name>Syntax</name> <name>Syntax</name>
<t>The child segment consists of a non-empty, comma-separated <t>The child segment consists of a non-empty, comma-separated
sequence of selectors enclosed in square brackets.</t> sequence of selectors enclosed in square brackets.</t>
skipping to change at line 2453 skipping to change at line 2426
child-segment = bracketed-selection / child-segment = bracketed-selection /
("." ("."
(wildcard-selector / (wildcard-selector /
member-name-shorthand)) member-name-shorthand))
bracketed-selection = "[" S selector *(S "," S selector) S "]" bracketed-selection = "[" S selector *(S "," S selector) S "]"
member-name-shorthand = name-first *name-char member-name-shorthand = name-first *name-char
name-first = ALPHA / name-first = ALPHA /
"_" / "_" /
%x80-D7FF / ; skip surrogate code points %x80-D7FF /
; skip surrogate code points
%xE000-10FFFF %xE000-10FFFF
name-char = DIGIT / name-first name-char = name-first / DIGIT
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
]]></sourcecode> ]]></sourcecode>
<t><tt>.*</tt>, a <tt>child-segment</tt> directly built from a <tt>w ildcard-selector</tt>, is <t><tt>.*</tt>, a <tt>child-segment</tt> directly built from a <tt>w ildcard-selector</tt>, is
shorthand for <tt>[*]</tt>.</t> shorthand for <tt>[*]</tt>.</t>
<t><tt>.&lt;member-name&gt;</tt>, a <tt>child-segment</tt> built fro m a <t><tt>.&lt;member-name&gt;</tt>, a <tt>child-segment</tt> built fro m a
<tt>member-name-shorthand</tt>, is shorthand for <tt>['&lt;member-name&gt;']</t t>. <tt>member-name-shorthand</tt>, is shorthand for <tt>['&lt;member-name&gt;']</t t>.
Note: this can only be used with member names that are composed of certain Note: This can only be used with member names that are composed of certain
characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>. characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>.
Thus, for example, <tt>$.foo.bar</tt> is shorthand for <tt>$['foo']['bar']</tt> (but not for <tt>$['foo.bar']</tt>).</t> Thus, for example, <tt>$.foo.bar</tt> is shorthand for <tt>$['foo']['bar']</tt> (but not for <tt>$['foo.bar']</tt>).</t>
</section> </section>
<section anchor="semantics-6"> <section anchor="semantics-6">
<name>Semantics</name> <name>Semantics</name>
<t>A child segment contains a sequence of selectors, each of which <t>A child segment contains a sequence of selectors, each of which
selects zero or more children of the input value.</t> selects zero or more children of the input value.</t>
<t>Selectors of different kinds may be combined within a single chil d segment.</t> <t>Selectors of different kinds may be combined within a single chil d segment.</t>
<t>For each node in the input nodelist, <t>For each node in the input nodelist,
the resulting nodelist of a child segment is the concatenation of the resulting nodelist of a child segment is the concatenation of
the nodelists from each of its selectors in the order that the selectors the nodelists from each of its selectors in the order that the selectors
appear in the list. appear in the list.
Note: any node matched by more than one selector is kept Note: Any node matched by more than one selector is kept
as many times in the nodelist.</t> as many times in the nodelist.</t>
<t>Where a selector can produce a nodelist in more than one possible order, <t>Where a selector can produce a nodelist in more than one possible order,
each occurrence of the selector in the child segment each occurrence of the selector in the child segment
may evaluate to produce a nodelist in a distinct order.</t> may produce a nodelist in a distinct order.</t>
<t>So a child segment drills down one more level into the structure <t>In summary, a child segment drills down one more level into the st
of the input value.</t> ructure of the input value.</t>
</section> </section>
<section anchor="examples-7"> <section anchor="examples-7">
<name>Examples</name> <name>Examples</name>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
["a", "b", "c", "d", "e", "f", "g"] ["a", "b", "c", "d", "e", "f", "g"]
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<table anchor="tbl-child-segment"> <table anchor="tbl-child-segment">
<name>Child segment examples</name> <name>Child Segment Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 2539 skipping to change at line 2513
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="descendant-segment"> <section anchor="descendant-segment">
<name>Descendant Segment</name> <name>Descendant Segment</name>
<section anchor="syntax-5"> <section anchor="syntax-5">
<name>Syntax</name> <name>Syntax</name>
<t>The descendant segment consists of a double dot <tt>..</tt> <t>The descendant segment consists of a double dot <tt>..</tt>
followed by a child segment (using bracket notation).</t> followed by a child segment (using bracket notation).</t>
<t>Shortand notations are also provided that correspond to the short hand forms of the child segment.</t> <t>Shorthand notations are also provided that correspond to the shor thand forms of the child segment.</t>
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[
descendant-segment = ".." (bracketed-selection / descendant-segment = ".." (bracketed-selection /
wildcard-selector / wildcard-selector /
member-name-shorthand) member-name-shorthand)
]]></sourcecode> ]]></sourcecode>
<t><tt>..*</tt>, the <tt>descendant-segment</tt> directly built from a <t><tt>..*</tt>, the <tt>descendant-segment</tt> directly built from a
<tt>wildcard-selector</tt>, is shorthand for <tt>..[*]</tt>.</t> <tt>wildcard-selector</tt>, is shorthand for <tt>..[*]</tt>.</t>
<t><tt>..&lt;member-name&gt;</tt>, a <tt>descendant-segment</tt> bui lt from a <t><tt>..&lt;member-name&gt;</tt>, a <tt>descendant-segment</tt> bui lt from a
<tt>member-name-shorthand</tt>, is shorthand for <tt>..['&lt;member-name&gt;']</ <tt>member-name-shorthand</tt>, is shorthand for <tt>..&wj;['&lt;member-name&gt;
tt>. ']</tt>.
Note: as with the similar shorthand of a <tt>child-segment</tt>, this can Note: As with the similar shorthand of a <tt>child-segment</tt>, this can
only be used with member names that are composed of certain only be used with member names that are composed of certain
characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>.</t> characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>.</t>
<t>Note: <tt>..</tt> on its own is not a valid segment.</t> <t>Note: On its own, <tt>..</tt> is not a valid segment.</t>
</section> </section>
<section anchor="semantics-7"> <section anchor="semantics-7">
<name>Semantics</name> <name>Semantics</name>
<t>A descendant segment produces zero or more descendants of an inpu t value.</t> <t>A descendant segment produces zero or more descendants of an inpu t value.</t>
<t>For each node in the input nodelist, <t>For each node in the input nodelist,
a descendant selector visits the input node and each of a descendant selector visits the input node and each of
its descendants such that:</t> its descendants such that:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>nodes of any array are visited in array order, and</li> <li>nodes of any array are visited in array order, and</li>
<li>nodes are visited before their descendants.</li> <li>nodes are visited before their descendants.</li>
</ul> </ul>
<t>The order in which the children of an object are visited is not s tipulated, since <t>The order in which the children of an object are visited is not s tipulated, since
JSON objects are unordered.</t> JSON objects are unordered.</t>
<t>Suppose the descendant segment is of the form <tt>..[&lt;selector <t>Suppose the descendant segment is of the form <tt>..&wj;[&lt;sele
s&gt;]</tt> (after converting any shorthand ctors&gt;]</tt> (after converting any shorthand
form to bracket notation) form to bracket notation),
and the nodes, in the order visited, are <tt>D1</tt>, ..., <tt>Dn</tt> (where <t t>n &gt;= 1</tt>). and the nodes, in the order visited, are <tt>D1</tt>, ..., <tt>Dn</tt> (where <t t>n &gt;= 1</tt>).
Note: <tt>D1</tt> is the input value.</t> Note: <tt>D1</tt> is the input value.</t>
<t>For each <tt>i</tt> such that <tt>1 &lt;= i &lt;= n</tt>, the nod elist <tt>Ri</tt> is defined to be a result of applying <t>For each <tt>i</tt> such that <tt>1 &lt;= i &lt;= n</tt>, the nod elist <tt>Ri</tt> is defined to be a result of applying
the child segment <tt>[&lt;selectors&gt;]</tt> to the node <tt>Di</tt>.</t> the child segment <tt>[&lt;selectors&gt;]</tt> to the node <tt>Di</tt>.</t>
<t>For each node in the input nodelist, <t>For each node in the input nodelist,
the result of the descendant segment is the concatenation of <tt>R1</tt>, the result of the descendant segment is the concatenation of <tt>R1</tt>,
..., <tt>Rn</tt> (in that order). ..., <tt>Rn</tt> (in that order).
These results are then concatenated in input nodelist order to form These results are then concatenated in input nodelist order to form
the result of the segment.</t> the result of the segment.</t>
<t>So a descendant segment drills down one or more levels into the s tructure of each input value.</t> <t>In summary, a descendant segment drills down one or more levels in to the structure of each input value.</t>
</section> </section>
<section anchor="examples-8"> <section anchor="examples-8">
<name>Examples</name> <name>Examples</name>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{ {
"o": {"j": 1, "k": 2}, "o": {"j": 1, "k": 2},
"a": [5, 3, [{"j": 4}, {"k": 6}]] "a": [5, 3, [{"j": 4}, {"k": 6}]]
} }
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<t>(Note that the fourth example can be expressed in two equivalent <t>(Note that the fourth example can be expressed in two equivalent
queries, shown here in one table row instead of two almost identical rows.)</t> queries, shown in <xref target="tbl-descendant-segment"/> in one table row inste ad of two almost-identical rows.)</t>
<table anchor="tbl-descendant-segment"> <table anchor="tbl-descendant-segment">
<name>Descendant segment examples</name> <name>Descendant Segment Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 2667 skipping to change at line 2641
<td align="center"> <td align="center">
<tt>$.a..[0, 1]</tt></td> <tt>$.a..[0, 1]</tt></td>
<td align="left"> <td align="left">
<tt>5</tt> <br/> <tt>3</tt> <br/> <tt>{"j": 4}</tt> <br/> <t t>{"k": 6}</tt></td> <tt>5</tt> <br/> <tt>3</tt> <br/> <tt>{"j": 4}</tt> <br/> <t t>{"k": 6}</tt></td>
<td align="center"> <td align="center">
<tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt> <br/> <tt>$['a'] [2][0]</tt> <br/> <tt>$['a'][2][1]</tt></td> <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt> <br/> <tt>$['a'] [2][0]</tt> <br/> <tt>$['a'][2][1]</tt></td>
<td align="left">Multiple segments</td> <td align="left">Multiple segments</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<t>Note: the ordering of the results for the <tt>$..[*]</tt> and <tt >$..*</tt> examples above is not guaranteed, except that:</t> <t>Note: The ordering of the results for the <tt>$..[*]</tt> and <tt >$..*</tt> examples above is not guaranteed, except that:</t>
<ul spacing="normal"> <ul spacing="normal">
<li> <li>
<tt>{"j": 1, "k": 2}</tt> must appear before <tt>1</tt> and <tt> 2</tt>,</li> <tt>{"j": 1, "k": 2}</tt> must appear before <tt>1</tt> and <tt> 2</tt>,</li>
<li> <li>
<tt>[5, 3, [{"j": 4}, {"k": 6}]]</tt> must appear before <tt>5</ tt>, <tt>3</tt>, and <tt>[{"j": 4}, {"k": 6}]</tt>,</li> <tt>[5, 3, [{"j": 4}, {"k": 6}]]</tt> must appear before <tt>5</ tt>, <tt>3</tt>, and <tt>[{"j": 4}, {"k": 6}]</tt>,</li>
<li> <li>
<tt>5</tt> must appear before <tt>3</tt> which must appear befor e <tt>[{"j": 4}, {"k": 6}]</tt>,</li> <tt>5</tt> must appear before <tt>3</tt>, which must appear befo re <tt>[{"j": 4}, {"k": 6}]</tt>,</li>
<li> <li>
<tt>5</tt> and <tt>3</tt> must appear before <tt>{"j": 4}</tt>, <tt>4</tt>, <tt>, {"k": 6}</tt>, and <tt>6</tt>,</li> <tt>5</tt> and <tt>3</tt> must appear before <tt>{"j": 4}</tt>, <tt>4</tt>, <tt>{"k": 6}</tt>, and <tt>6</tt>,</li>
<li> <li>
<tt>[{"j": 4}, {"k": 6}]</tt> must appear before <tt>{"j": 4}</t t> and <tt>{"k": 6}</tt>,</li> <tt>[{"j": 4}, {"k": 6}]</tt> must appear before <tt>{"j": 4}</t t> and <tt>{"k": 6}</tt>,</li>
<li> <li>
<tt>{"j": 4}</tt> must appear before <tt>{"k": 6}</tt>,</li> <tt>{"j": 4}</tt> must appear before <tt>{"k": 6}</tt>,</li>
<li> <li>
<tt>{"k": 6}</tt> must appear before <tt>4</tt>, and</li> <tt>{"k": 6}</tt> must appear before <tt>4</tt>, and</li>
<li> <li>
<tt>4</tt> must appear before <tt>6</tt>.</li> <tt>4</tt> must appear before <tt>6</tt>.</li>
</ul> </ul>
<t>The example above with the query <tt>$.o..[*, *]</tt> shows that a selector may produce nodelists in distinct orders <t>The example above with the query <tt>$.o..[*, *]</tt> shows that a selector may produce nodelists in distinct orders
each time it appears in the descendant segment.</t> each time it appears in the descendant segment.</t>
<t>The example above with the query <tt>$.a..[0, 1]</tt> shows that the child segment <tt>[0, 1]</tt> is applied to each node <t>The example above with the query <tt>$.a..[0, 1]</tt> shows that the child segment <tt>[0, 1]</tt> is applied to each node
in turn (rather than the nodes being visited once per selector, which is the cas e for some JSONPath implementations in turn (rather than the nodes being visited once per selector, which is the cas e for some JSONPath implementations
that do not conform to this specification).</t> that do not conform to this specification).</t>
</section> </section>
</section> </section>
</section> </section>
<section anchor="null-semantics"> <section anchor="null-semantics">
<name>Semantics of <tt>null</tt></name> <name>Semantics of <tt>null</tt></name>
<t>Note: JSON <tt>null</tt> is treated the same as any other JSON value: it is not taken to mean "undefined" or "missing".</t> <t>Note: JSON <tt>null</tt> is treated the same as any other JSON value, i.e., it is not taken to mean "undefined" or "missing".</t>
<section anchor="examples-9"> <section anchor="examples-9">
<name>Examples</name> <name>Examples</name>
<t>JSON:</t> <t>JSON:</t>
<sourcecode type="json"><![CDATA[ <sourcecode type="json"><![CDATA[
{"a": null, "b": [null], "c": [{}], "null": 1} {"a": null, "b": [null], "c": [{}], "null": 1}
]]></sourcecode> ]]></sourcecode>
<t>Queries:</t> <t>Queries:</t>
<table anchor="tbl-null-examples"> <table anchor="tbl-null-examples">
<name>Examples involving (or not involving) null</name> <name>Examples Involving (or Not Involving) <tt>null</tt></name>
<thead> <thead>
<tr> <tr>
<th align="center">Query</th> <th align="center">Query</th>
<th align="left">Result</th> <th align="left">Result</th>
<th align="center">Result Paths</th> <th align="center">Result Paths</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
skipping to change at line 2727 skipping to change at line 2701
<tt>$.a</tt></td> <tt>$.a</tt></td>
<td align="left"> <td align="left">
<tt>null</tt></td> <tt>null</tt></td>
<td align="center"> <td align="center">
<tt>$['a']</tt></td> <tt>$['a']</tt></td>
<td align="left">Object value</td> <td align="left">Object value</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.a[0]</tt></td> <tt>$.a[0]</tt></td>
<td align="left"> </td> <td align="left"> </td>
<td align="center"> </td> <td align="center"> </td>
<td align="left"> <td align="left">
<tt>null</tt> used as array</td> <tt>null</tt> used as array</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.a.d</tt></td> <tt>$.a.d</tt></td>
<td align="left"> </td> <td align="left"> </td>
<td align="center"> </td> <td align="center"> </td>
<td align="left"> <td align="left">
<tt>null</tt> used as object</td> <tt>null</tt> used as object</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.b[0]</tt></td> <tt>$.b[0]</tt></td>
<td align="left"> <td align="left">
<tt>null</tt></td> <tt>null</tt></td>
<td align="center"> <td align="center">
<tt>$['b'][0]</tt></td> <tt>$['b'][0]</tt></td>
skipping to change at line 2779 skipping to change at line 2753
<tt>$.b[?@==null]</tt></td> <tt>$.b[?@==null]</tt></td>
<td align="left"> <td align="left">
<tt>null</tt></td> <tt>null</tt></td>
<td align="center"> <td align="center">
<tt>$['b'][0]</tt></td> <tt>$['b'][0]</tt></td>
<td align="left">Comparison</td> <td align="left">Comparison</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.c[?@.d==null]</tt></td> <tt>$.c[?@.d==null]</tt></td>
<td align="left"> </td> <td align="left"> </td>
<td align="center"> </td> <td align="center"> </td>
<td align="left">Comparison with "missing" value</td> <td align="left">Comparison with "missing" value</td>
</tr> </tr>
<tr> <tr>
<td align="center"> <td align="center">
<tt>$.null</tt></td> <tt>$.null</tt></td>
<td align="left"> <td align="left">
<tt>1</tt></td> <tt>1</tt></td>
<td align="center"> <td align="center">
<tt>$['null']</tt></td> <tt>$['null']</tt></td>
<td align="left">Not JSON null at all, just a member name string </td> <td align="left">Not JSON <tt>null</tt> at all, just a member na me string</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="normalized-paths"> <section anchor="normalized-paths">
<name>Normalized Paths</name> <name>Normalized Paths</name>
<t>A Normalized Path is a unique representation of the location of a nod e in a value which <t>A Normalized Path is a unique representation of the location of a nod e in a value that
uniquely identifies the node in the value. uniquely identifies the node in the value.
Specifically, a Normalized Path is a JSONPath query with restricted syntax (defi ned below), Specifically, a Normalized Path is a JSONPath query with restricted syntax (defi ned below),
e.g., <tt>$['book'][3]</tt>, which when applied to the value results in a nodeli st consisting e.g., <tt>$['book'][3]</tt>, which when applied to the value, results in a nodel ist consisting
of just the node identified by the Normalized Path. of just the node identified by the Normalized Path.
Note: a Normalized Path represents the identity of a node <em>in a specific valu e</em>. Note: A Normalized Path represents the identity of a node <em>in a specific valu e</em>.
There is precisely one Normalized Path identifying any particular node in a valu e.</t> There is precisely one Normalized Path identifying any particular node in a valu e.</t>
<t>A nodelist may be represented compactly in JSON as an array of string s, where the strings are <t>A nodelist may be represented compactly in JSON as an array of string s, where the strings are
Normalized Paths.</t> Normalized Paths.</t>
<t>Normalized Paths provide a predictable format that simplifies testing and post-processing <t>Normalized Paths provide a predictable format that simplifies testing and post-processing
of nodelists, e.g., to remove duplicate nodes. of nodelists, e.g., to remove duplicate nodes.
Normalized Paths are used in this document as result paths in examples.</t> Normalized Paths are used in this document as result paths in examples.</t>
<t>Normalized Paths use the canonical bracket notation, rather than dot notation.</t> <t>Normalized Paths use the canonical bracket notation, rather than dot notation.</t>
<t>Single quotes are used in Normalized Paths to delimit string member n ames. This reduces the <t>Single quotes are used in Normalized Paths to delimit string member n ames. This reduces the
number of characters that need escaping when Normalized Paths appear in double q number of characters that need escaping when Normalized Paths appear in
uote-delimited strings delimited by double quotes, e.g., in JSON texts.</t>
strings, e.g., in JSON texts.</t> <t>Certain characters are escaped in Normalized Paths in one and only on
<t>Certain characters are escaped in Normalized Paths, in one and only o e way; all other
ne way; all other characters are unescaped.</t>
characters are unescaped.</t> <aside>
<t>Note: Normalized Paths are singular queries, but not all singular que ries are Normalized Paths. <t>Note: Normalized Paths are singular queries, but not all singular que ries are Normalized Paths.
For example, <tt>$[-3]</tt> is a singular query, but is not a Normalized Path. For example, <tt>$[-3]</tt> is a singular query but is not a Normalized Path.
The Normalized Path equivalent to <tt>$[-3]</tt> would have an index equal to th e array length minus <tt>3</tt>. The Normalized Path equivalent to <tt>$[-3]</tt> would have an index equal to th e array length minus <tt>3</tt>.
(The array length must be at least <tt>3</tt> if <tt>$[-3]</tt> is to identify a (The array length must be at least <tt>3</tt> if <tt>$[-3]</tt> is to ide
node.)</t> ntify a node.)</t>
</aside>
<sourcecode type="abnf" name="normalized-path-collected.abnf"><![CDATA[ <sourcecode type="abnf" name="normalized-path-collected.abnf"><![CDATA[
normalized-path = root-identifier *(normal-index-segment) normalized-path = root-identifier *(normal-index-segment)
normal-index-segment = "[" normal-selector "]" normal-index-segment = "[" normal-selector "]"
normal-selector = normal-name-selector / normal-index-selector normal-selector = normal-name-selector / normal-index-selector
normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string'
normal-single-quoted = normal-unescaped / normal-single-quoted = normal-unescaped /
ESC normal-escapable ESC normal-escapable
normal-unescaped = ; omit %x0-1F control codes normal-unescaped = ; omit %x0-1F control codes
%x20-26 / %x20-26 /
; omit 0x27 ' ; omit 0x27 '
%x28-5B / %x28-5B /
; omit 0x5C \ ; omit 0x5C \
%x5D-D7FF / ; skip surrogate code points %x5D-D7FF /
; skip surrogate code points
%xE000-10FFFF %xE000-10FFFF
normal-escapable = %x62 / ; b BS backspace U+0008 normal-escapable = %x62 / ; b BS backspace U+0008
%x66 / ; f FF form feed U+000C %x66 / ; f FF form feed U+000C
%x6E / ; n LF line feed U+000A %x6E / ; n LF line feed U+000A
%x72 / ; r CR carriage return U+000D %x72 / ; r CR carriage return U+000D
%x74 / ; t HT horizontal tab U+0009 %x74 / ; t HT horizontal tab U+0009
"'" / ; ' apostrophe U+0027 "'" / ; ' apostrophe U+0027
"\" / ; \ backslash (reverse solidus) U+005C "\" / ; \ backslash (reverse solidus) U+005C
(%x75 normal-hexchar) (%x75 normal-hexchar)
; certain values u00xx U+00XX ; certain values u00xx U+00XX
normal-hexchar = "0" "0" normal-hexchar = "0" "0"
( (
("0" %x30-37) / ; "00"-"07" ("0" %x30-37) / ; "00"-"07"
; omit U+0008-U+000A BS HT LF ; omit U+0008-U+000A BS HT LF
("0" %x62) / ; "0b" ("0" %x62) / ; "0b"
; omit U+000C-U+000D FF CR ; omit U+000C-U+000D FF CR
("0" %x65-66) / ; "0e"-"0f" ("0" %x65-66) / ; "0e"-"0f"
("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-index-selector = "0" / (DIGIT1 *DIGIT) normal-index-selector = "0" / (DIGIT1 *DIGIT)
; non-negative decimal integer ; non-negative decimal integer
]]></sourcecode> ]]></sourcecode>
<t>Since there can only be one Normalized Path identifying a given node, the syntax <t>Since there can only be one Normalized Path identifying a given node, the syntax
stipulates which characters are escaped and which are not. stipulates which characters are escaped and which are not.
So the definition of <tt>normal-hexchar</tt> is designed for hex escaping of cha racters So the definition of <tt>normal-hexchar</tt> is designed for hex escaping of cha racters
which are not straightforwardly printable, for example U+000B LINE TABULATION, b ut that are not straightforwardly printable, for example, U+000B LINE TABULATION, b ut
for which no standard JSON escape, such as <tt>\n</tt>, is available.</t> for which no standard JSON escape, such as <tt>\n</tt>, is available.</t>
<section anchor="examples-10"> <section anchor="examples-10">
<name>Examples</name> <name>Examples</name>
<table anchor="tbl-normalized-path-examples"> <table anchor="tbl-normalized-path-examples">
<name>Normalized Path examples</name> <name>Normalized Path Examples</name>
<thead> <thead>
<tr> <tr>
<th align="center">Path</th> <th align="center">Path</th>
<th align="center">Normalized Path</th> <th align="center">Normalized Path</th>
<th align="left">Comment</th> <th align="left">Comment</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="center"> <td align="center">
skipping to change at line 2922 skipping to change at line 2899
<td align="center"> <td align="center">
<tt>$['a']</tt></td> <tt>$['a']</tt></td>
<td align="left">Unicode character</td> <td align="left">Unicode character</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
</section> </section>
<section anchor="IANA"> <section anchor="IANA">
<name>IANA Considerations</name> <name>IANA Considerations</name>
<t><cref anchor="replace-xxxx">RFC Ed.: throughout this section, please re
place
RFCXXXX with the RFC number of this specification and remove this
note.</cref></t>
<section anchor="registration-of-media-type-applicationjsonpath"> <section anchor="registration-of-media-type-applicationjsonpath">
<name>Registration of Media Type application/jsonpath</name> <name>Registration of Media Type application/jsonpath</name>
<t>IANA is requested to register the following media type <xref target=" RFC6838"/>:</t> <t>IANA has registered the following media type <xref target="RFC6838"/> :</t>
<dl> <dl>
<dt>Type name:</dt> <dt>Type name:</dt>
<dd> <dd>
<t>application</t> <t>application</t>
</dd> </dd>
<dt>Subtype name:</dt> <dt>Subtype name:</dt>
<dd> <dd>
<t>jsonpath</t> <t>jsonpath</t>
</dd> </dd>
<dt>Required parameters:</dt> <dt>Required parameters:</dt>
skipping to change at line 2952 skipping to change at line 2927
<dt>Optional parameters:</dt> <dt>Optional parameters:</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>Encoding considerations:</dt> <dt>Encoding considerations:</dt>
<dd> <dd>
<t>binary (UTF-8)</t> <t>binary (UTF-8)</t>
</dd> </dd>
<dt>Security considerations:</dt> <dt>Security considerations:</dt>
<dd> <dd>
<t>See the Security Considerations section of RFCXXXX.</t> <t>See the Security Considerations section of RFC 9535.</t>
</dd> </dd>
<dt>Interoperability considerations:</dt> <dt>Interoperability considerations:</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>Published specification:</dt> <dt>Published specification:</dt>
<dd> <dd>
<t>RFCXXXX</t> <t>RFC 9535</t>
</dd> </dd>
<dt>Applications that use this media type:</dt> <dt>Applications that use this media type:</dt>
<dd> <dd>
<t>Applications that need to convey queries in JSON data</t> <t>Applications that need to convey queries in JSON data</t>
</dd> </dd>
<dt>Fragment identifier considerations:</dt> <dt>Fragment identifier considerations:</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>Additional information:</dt> <dt>Additional information:</dt>
<dd> <dd><t><br/></t>
<dl> <dl spacing="compact">
<dt>Deprecated alias names for this type:</dt> <dt>Deprecated alias names for this type:</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>Magic number(s):</dt> <dt>Magic number(s):</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>File extension(s):</dt> <dt>File extension(s):</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>Macintosh file type code(s):</dt> <dt>Macintosh file type code(s):</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
</dl> </dl>
</dd> </dd>
</dl> <dt>Person &amp; email address to contact for further information:</dt>
<t>Person &amp; email address to contact for further information: <dd>iesg@ietf.org</dd>
iesg@ietf.org</t>
<dl>
<dt>Intended usage:</dt> <dt>Intended usage:</dt>
<dd> <dd>
<t>COMMON</t> <t>COMMON</t>
</dd> </dd>
<dt>Restrictions on usage:</dt> <dt>Restrictions on usage:</dt>
<dd> <dd>
<t>N/A</t> <t>N/A</t>
</dd> </dd>
<dt>Author:</dt> <dt>Author:</dt>
<dd> <dd>
<t>JSONPath WG</t> <t>JSONPath WG</t>
</dd> </dd>
<dt>Change controller:</dt> <dt>Change controller:</dt>
<dd> <dd>
<t>IETF</t> <t>IETF</t>
</dd> </dd>
<dt>Provisional registration? (standards tree only):</dt>
<dd>
<t>no</t>
</dd>
</dl> </dl>
</section> </section>
<section anchor="iana-fnex"> <section anchor="iana-fnex">
<name>Function Extensions</name> <name>Function Extensions Subregistry</name>
<t>This specification defines a new "Function Extensions sub-registry" i <t>Per this specification, IANA has created a new "Function Extensions"
n subregistry in
a new "JSONPath Parameters registry", with the policy "expert review" a new "JSONPath" registry. The "Function Extensions" subregistry has the policy
(<xref section="4.5" sectionFormat="of" target="BCP26"/>).</t> "Expert Review"
(<xref section="4.5" sectionFormat="of" target="RFC8126"></xref>).</t>
<t anchor="de-instructions">The experts are instructed to be frugal in t he allocation of function <t anchor="de-instructions">The experts are instructed to be frugal in t he allocation of function
extension names that are suggestive of generally applicable semantics, extension names that are suggestive of generally applicable semantics,
keeping them in reserve for functions that are likely to enjoy wide keeping them in reserve for functions that are likely to enjoy wide
use and can make good use of their conciseness. use and can make good use of their conciseness.
The expert is also instructed to direct the registrant to provide a The expert is also instructed to direct the registrant to provide a
specification (<xref section="4.6" sectionFormat="of" target="BCP26"/>), but can specification (<xref section="4.6" sectionFormat="of" target="RFC8126"></xref>)
make exceptions, but can make exceptions,
for instance when a specification is not available at the time of for instance, when a specification is not available at the time of
registration but is likely forthcoming. registration but is likely forthcoming.
If the expert becomes aware of function extensions that are deployed and If the expert becomes aware of function extensions that are deployed and
in use, they may also initiate a registration on their own if in use, they may also initiate a registration on their own if
they deem such a registration can avert potential future collisions.</t> they deem such a registration can avert potential future collisions.</t>
<t>Each entry in the sub-registry must include:</t> <t>Each entry in the subregistry must include the following:</t>
<dl newline="true"> <dl newline="true">
<dt>Function Name:</dt> <dt>Function Name:</dt>
<dd> <dd>
<t>a lower case ASCII <xref target="STD80"/> string that starts with <t>A lowercase ASCII <xref target="RFC0020"/> string that starts wit
a letter and can h a letter and can
contain letters, digits and underscore characters afterwards contain letters, digits, and underscore characters afterwards
(<tt>[a-z][_a-z0-9]*</tt>). No other entry in the sub-registry can have the (<tt>[a-z][_a-z0-9]*</tt>). No other entry in the subregistry can have the
same function name.</t> same function name.</t>
</dd> </dd>
<dt>Brief description:</dt> <dt>Brief description:</dt>
<dd> <dd>
<t>a brief description</t> <t>A brief description</t>
</dd> </dd>
<dt>Parameters:</dt> <dt>Parameters:</dt>
<dd> <dd>
<t>A comma-separated list of zero or more declared types, one for ea ch of the <t>A comma-separated list of zero or more declared types, one for ea ch of the
arguments expected for this function extension</t> arguments expected for this function extension</t>
</dd> </dd>
<dt>Result:</dt> <dt>Result:</dt>
<dd> <dd>
<t>The declared type of the result for this function extension</t> <t>The declared type of the result for this function extension</t>
</dd> </dd>
<dt>Change Controller:</dt> <dt>Change Controller:</dt>
<dd> <dd>
<t>(see <xref section="2.3" sectionFormat="of" target="BCP26"/>)</t> <t>See <xref section="2.3" sectionFormat="of" target="RFC8126"></xre f>.</t>
</dd> </dd>
<dt>Reference:</dt> <dt>Reference:</dt>
<dd> <dd>
<t>a reference document that provides a description of the function <t>A reference document that provides a description of the function
extension</t> extension</t>
</dd> </dd>
</dl> </dl>
<t>Initial entries in this sub-registry are as listed in <xref target="p <t>The initial entries in this subregistry are listed in <xref target="p
re-reg"/>; the re-reg"/>; the
entries in the Column "Change Controller" all have the value "IETF" entries in the "Change Controller" column all have the value "IETF",
and the entries in the column and the entries in the
"Reference" all have the value "<xref target="fnex"/> of RFCXXXX":</t> "Reference" column all have the value "<xref target="fnex"/> of RFC 9535":</t>
<table anchor="pre-reg"> <table anchor="pre-reg">
<name>Initial Entries in the Function Extensions Subregistry</name> <name>Initial Entries in the Function Extensions Subregistry</name>
<thead> <thead>
<tr> <tr>
<th align="left">Function Name</th> <th align="left">Function Name</th>
<th align="left">Brief description</th> <th align="left">Brief Description</th>
<th align="left">Parameters</th> <th align="left">Parameters</th>
<th align="left">Result</th> <th align="left">Result</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left">length</td> <td align="left">length</td>
<td align="left">length of string, array, object</td> <td align="left">length of string, array, or object</td>
<td align="left"> <td align="left">
<tt>ValueType</tt></td> <tt>ValueType</tt></td>
<td align="left"> <td align="left">
<tt>ValueType</tt></td> <tt>ValueType</tt></td>
</tr> </tr>
<tr> <tr>
<td align="left">count</td> <td align="left">count</td>
<td align="left">size of nodelist</td> <td align="left">size of nodelist</td>
<td align="left"> <td align="left">
<tt>NodesType</tt></td> <tt>NodesType</tt></td>
skipping to change at line 3114 skipping to change at line 3083
<tr> <tr>
<td align="left">search</td> <td align="left">search</td>
<td align="left">regular expression substring match</td> <td align="left">regular expression substring match</td>
<td align="left"> <td align="left">
<tt>ValueType</tt>, <tt>ValueType</tt></td> <tt>ValueType</tt>, <tt>ValueType</tt></td>
<td align="left"> <td align="left">
<tt>LogicalType</tt></td> <tt>LogicalType</tt></td>
</tr> </tr>
<tr> <tr>
<td align="left">value</td> <td align="left">value</td>
<td align="left">value of single node in nodelist</td> <td align="left">value of the single node in nodelist</td>
<td align="left"> <td align="left">
<tt>NodesType</tt></td> <tt>NodesType</tt></td>
<td align="left"> <td align="left">
<tt>ValueType</tt></td> <tt>ValueType</tt></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</section> </section>
<section anchor="Security"> <section anchor="Security">
<name>Security Considerations</name> <name>Security Considerations</name>
<t>Security considerations for JSONPath can stem from</t> <t>Security considerations for JSONPath can stem from:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>attack vectors on JSONPath implementations,</li> <li>attack vectors on JSONPath implementations,</li>
<li>attack vectors on how JSONPath queries are formed, and</li> <li>attack vectors on how JSONPath queries are formed, and</li>
<li>the way JSONPath is used in security-relevant mechanisms.</li> <li>the way JSONPath is used in security-relevant mechanisms.</li>
</ul> </ul>
<section anchor="attack-vectors-on-jsonpath-implementations"> <section anchor="attack-vectors-on-jsonpath-implementations">
<name>Attack Vectors on JSONPath Implementations</name> <name>Attack Vectors on JSONPath Implementations</name>
<t>Historically, JSONPath has often been implemented by feeding parts of <t>Historically, JSONPath has often been implemented by feeding parts of
the query to an underlying programming language engine, e.g., the query to an underlying programming language engine, e.g.,
JavaScript's <tt>eval()</tt> function. JavaScript's <tt>eval()</tt> function.
This approach is well known to lead to injection attacks and would This approach is well known to lead to injection attacks and would
require perfect input validation to prevent these attacks (see require perfect input validation to prevent these attacks (see
<xref section="12" sectionFormat="of" target="RFC8259"/> for similar considerati ons for JSON itself). <xref section="12" sectionFormat="of" target="RFC8259"/> for similar considerati ons for JSON itself).
Instead, JSONPath implementations need to implement the entire syntax Instead, JSONPath implementations need to implement the entire syntax
of the query without relying on the parsers of programming language of the query without relying on the parsers of programming language
engines.</t> engines.</t>
<t>Attacks on availability may attempt to trigger unusually expensive <t>Attacks on availability may attempt to trigger unusually expensive
runtime performance exhibited by certain implementations in certain runtime performance exhibited by certain implementations in certain
cases. cases.
(See <xref section="10" sectionFormat="of" target="RFC8949"/> for issues in hash (See <xref section="10" sectionFormat="of" target="RFC8949"/> for issues in hash
-table implementations, -table implementations
and <xref section="8" sectionFormat="of" target="I-D.draft-ietf-jsonpath-iregexp and <xref section="8" sectionFormat="of" target="RFC9485"/> for performance issu
"/> for performance issues in regular es in regular
expression implementations.) expression implementations.)
Implementers need to be aware that good average performance is not Implementers need to be aware that good average performance is not
sufficient as long as an attacker can choose to submit specially sufficient as long as an attacker can choose to submit specially
crafted JSONPath queries or query arguments that trigger surprisingly high, poss ibly crafted JSONPath queries or query arguments that trigger surprisingly high, poss ibly
exponential, CPU usage or, for example via a naive recursive implementation of t he descendant segment, exponential, CPU usage or, for example, via a naive recursive implementation of the descendant segment,
stack overflow. Implementations need to have appropriate resource management stack overflow. Implementations need to have appropriate resource management
to mitigate these attacks.</t> to mitigate these attacks.</t>
</section> </section>
<section anchor="attack-vectors-on-how-jsonpath-queries-are-formed"> <section anchor="attack-vectors-on-how-jsonpath-queries-are-formed">
<name>Attack Vectors on How JSONPath Queries are Formed</name> <name>Attack Vectors on How JSONPath Queries Are Formed</name>
<t>JSONPath queries are often not static, but formed from variables that <t>JSONPath queries are often not static but formed from variables that
provide index values, member names, or values to compare with in a provide index values, member names, or values to compare with in a
filter expression. filter expression.
These variables need to be validated (e.g., only allowing specific constructs These variables need to be validated (e.g., only allowing specific constructs
such as .name to be formed when the given values allow that) and translated such as .name to be formed when the given values allow that) and translated
(e.g., by escaping string delimiters). (e.g., by escaping string delimiters).
Not performing these validations and translations correctly can lead to unexpect ed Not performing these validations and translations correctly can lead to unexpect ed
failures, which can lead to Availability, Confidentiality, and failures, which can lead to availability, confidentiality, and
Integrity breaches, in particular if an adversary has control over the integrity breaches, in particular, if an adversary has control over the
values (e.g., by entering them into a Web form). values (e.g., by entering them into a web form).
The resulting class of attacks, <em>injections</em> (e.g., SQL injections), The resulting class of attacks, <em>injections</em> (e.g., SQL injections),
is consistently found among the top causes of application security is consistently found among the top causes of application security
vulnerabilities and requires particular attention.</t> vulnerabilities and requires particular attention.</t>
</section> </section>
<section anchor="attacks-on-security-mechanisms-that-employ-jsonpath"> <section anchor="attacks-on-security-mechanisms-that-employ-jsonpath">
<name>Attacks on Security Mechanisms that Employ JSONPath</name> <name>Attacks on Security Mechanisms That Employ JSONPath</name>
<t>Where JSONPath is used as a part of a security mechanism, attackers <t>Where JSONPath is used as a part of a security mechanism, attackers
can attempt to provoke unexpected or unpredictable behavior, or can attempt to provoke unexpected or unpredictable behavior or
take advantage of differences in behavior between JSONPath implementations.</t> take advantage of differences in behavior between JSONPath implementations.</t>
<t>Unexpected or unpredictable behavior can arise from a query argument with certain <t>Unexpected or unpredictable behavior can arise from a query argument with certain
constructs described as unpredictable by <xref target="RFC8259"/>. constructs described as unpredictable by <xref target="RFC8259"/>.
Predictable behavior can be expected, except in relation to the ordering Predictable behavior can be expected, except in relation to the ordering
of objects, for any query argument conforming with <xref target="RFC7493"/>.</t> of objects, for any query argument conforming with <xref target="RFC7493"/>.</t>
<t>Other attacks can target the behavior of underlying technologies such as UTF-8 (see <t>Other attacks can target the behavior of underlying technologies, suc h as UTF-8 (see
<xref section="10" sectionFormat="of" target="RFC3629"/>) and the Unicode charac ter set.</t> <xref section="10" sectionFormat="of" target="RFC3629"/>) and the Unicode charac ter set.</t>
</section> </section>
</section> </section>
</middle> </middle>
<back> <back>
<references> <references>
<name>References</name> <name>References</name>
<references anchor="sec-normative-references"> <references anchor="sec-normative-references">
<name>Normative References</name> <name>Normative References</name>
<reference anchor="STD80">
<front>
<title>ASCII format for network interchange</title>
<author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/>
<date month="October" year="1969"/>
</front>
<seriesInfo name="STD" value="80"/>
<seriesInfo name="RFC" value="20"/>
<seriesInfo name="DOI" value="10.17487/RFC0020"/>
</reference>
<reference anchor="BCP26">
<front>
<title>Guidelines for Writing an IANA Considerations Section in RFCs
</title>
<author fullname="M. Cotton" initials="M." surname="Cotton"/>
<author fullname="B. Leiba" initials="B." surname="Leiba"/>
<author fullname="T. Narten" initials="T." surname="Narten"/>
<date month="June" year="2017"/>
<abstract>
<t>Many protocols make use of points of extensibility that use con
stants to identify various protocol parameters. To ensure that the values in the
se fields do not have conflicting uses and to promote interoperability, their al
locations are often coordinated by a central record keeper. For IETF protocols,
that role is filled by the Internet Assigned Numbers Authority (IANA).</t>
<t>To make assignments in a given registry prudently, guidance des
cribing the conditions under which new values should be assigned, as well as whe
n and how modifications to existing values can be made, is needed. This document
defines a framework for the documentation of these guidelines by specification
authors, in order to assure that the provided guidance for the IANA Consideratio
ns is clear and addresses the various issues that are likely in the operation of
a registry.</t>
<t>This is the third edition of this document; it obsoletes RFC 52
26.</t>
</abstract>
</front>
<seriesInfo name="BCP" value="26"/>
<seriesInfo name="RFC" value="8126"/>
<seriesInfo name="DOI" value="10.17487/RFC8126"/>
</reference>
<reference anchor="RFC3629">
<front>
<title>UTF-8, a transformation format of ISO 10646</title>
<author fullname="F. Yergeau" initials="F." surname="Yergeau"/>
<date month="November" year="2003"/>
<abstract>
<t>ISO/IEC 10646-1 defines a large character set called the Univer
sal Character Set (UCS) which encompasses most of the world's writing systems. T
he originally proposed encodings of the UCS, however, were not compatible with m
any current applications and protocols, and this has led to the development of U
TF-8, the object of this memo. UTF-8 has the characteristic of preserving the fu
ll US-ASCII range, providing compatibility with file systems, parsers and other
software that rely on US-ASCII values but are transparent to other values. This
memo obsoletes and replaces RFC 2279.</t>
</abstract>
</front>
<seriesInfo name="STD" value="63"/>
<seriesInfo name="RFC" value="3629"/>
<seriesInfo name="DOI" value="10.17487/RFC3629"/>
</reference>
<reference anchor="RFC5234">
<front>
<title>Augmented BNF for Syntax Specifications: ABNF</title>
<author fullname="D. Crocker" initials="D." role="editor" surname="C
rocker"/>
<author fullname="P. Overell" initials="P." surname="Overell"/>
<date month="January" year="2008"/>
<abstract>
<t>Internet technical specifications often need to define a formal
syntax. Over the years, a modified version of Backus-Naur Form (BNF), called Au
gmented BNF (ABNF), has been popular among many Internet specifications. The cur
rent specification documents ABNF. It balances compactness and simplicity with r
easonable representational power. The differences between standard BNF and ABNF
involve naming rules, repetition, alternatives, order-independence, and value ra
nges. This specification also supplies additional rule definitions and encoding
for a core lexical analyzer of the type common to several Internet specification
s. [STANDARDS-TRACK]</t>
</abstract>
</front>
<seriesInfo name="STD" value="68"/>
<seriesInfo name="RFC" value="5234"/>
<seriesInfo name="DOI" value="10.17487/RFC5234"/>
</reference>
<reference anchor="RFC8259">
<front>
<title>The JavaScript Object Notation (JSON) Data Interchange Format
</title>
<author fullname="T. Bray" initials="T." role="editor" surname="Bray
"/>
<date month="December" year="2017"/>
<abstract>
<t>JavaScript Object Notation (JSON) is a lightweight, text-based,
language-independent data interchange format. It was derived from the ECMAScrip
t Programming Language Standard. JSON defines a small set of formatting rules fo
r the portable representation of structured data.</t>
<t>This document removes inconsistencies with other specifications
of JSON, repairs specification errors, and offers experience-based interoperabi
lity guidance.</t>
</abstract>
</front>
<seriesInfo name="STD" value="90"/>
<seriesInfo name="RFC" value="8259"/>
<seriesInfo name="DOI" value="10.17487/RFC8259"/>
</reference>
<reference anchor="RFC7493">
<front>
<title>The I-JSON Message Format</title>
<author fullname="T. Bray" initials="T." role="editor" surname="Bray
"/>
<date month="March" year="2015"/>
<abstract>
<t>I-JSON (short for "Internet JSON") is a restricted profile of J
SON designed to maximize interoperability and increase confidence that software
can process it successfully with predictable results.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="7493"/>
<seriesInfo name="DOI" value="10.17487/RFC7493"/>
</reference>
<reference anchor="RFC6838">
<front>
<title>Media Type Specifications and Registration Procedures</title>
<author fullname="N. Freed" initials="N." surname="Freed"/>
<author fullname="J. Klensin" initials="J." surname="Klensin"/>
<author fullname="T. Hansen" initials="T." surname="Hansen"/>
<date month="January" year="2013"/>
<abstract>
<t>This document defines procedures for the specification and regi
stration of media types for use in HTTP, MIME, and other Internet protocols. Thi
s memo documents an Internet Best Current Practice.</t>
</abstract>
</front>
<seriesInfo name="BCP" value="13"/>
<seriesInfo name="RFC" value="6838"/>
<seriesInfo name="DOI" value="10.17487/RFC6838"/>
</reference>
<reference anchor="I-D.draft-ietf-jsonpath-iregexp">
<front>
<title>I-Regexp: An Interoperable Regexp Format</title>
<author fullname="Carsten Bormann" initials="C." surname="Bormann">
<organization>Universität Bremen TZI</organization>
</author>
<author fullname="Tim Bray" initials="T." surname="Bray">
<organization>Textuality</organization>
</author>
<date day="29" month="June" year="2023"/>
<abstract>
<t> This document specifies I-Regexp, a flavor of regular expres
sions
that is limited in scope with the goal of interoperation across many
different regular-expression libraries.
</t> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0020.xml"
</abstract> />
</front> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xm
<seriesInfo name="Internet-Draft" value="draft-ietf-jsonpath-iregexp-0 l"/>
8"/> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3629.xml"
</reference> />
<reference anchor="UNICODE" target="https://www.unicode.org/versions/Uni <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"
code14.0.0/UnicodeStandard-14.0.pdf"> />
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7493.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6838.xml"
/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9485.xml"
/>
<reference anchor="UNICODE" target="https://www.unicode.org/versions/lat
est/">
<front> <front>
<title>The Unicode® Standard: Version 14.0 - Core Specification</tit le> <title>The Unicode® Standard</title>
<author> <author>
<organization>The Unicode Consortium</organization> <organization>The Unicode Consortium</organization>
</author> </author>
<date year="2021" month="September"/>
</front> </front>
<annotation>At the time of writing, <eref target="https://www.unicode.o rg/versions/Unicode15.0.0/UnicodeStandard-15.0.pdf" brackets="angle"/>.</annotat ion>
</reference> </reference>
<reference anchor="RFC2119">
<front> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"
<title>Key words for use in RFCs to Indicate Requirement Levels</tit />
le> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"
<author fullname="S. Bradner" initials="S." surname="Bradner"/> />
<date month="March" year="1997"/>
<abstract>
<t>In many standards track documents several words are used to sig
nify the requirements in the specification. These words are often capitalized. T
his document defines these words as they should be interpreted in IETF documents
. This document specifies an Internet Best Current Practices for the Internet Co
mmunity, and requests discussion and suggestions for improvements.</t>
</abstract>
</front>
<seriesInfo name="BCP" value="14"/>
<seriesInfo name="RFC" value="2119"/>
<seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>
<reference anchor="RFC8174">
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</ti
tle>
<author fullname="B. Leiba" initials="B." surname="Leiba"/>
<date month="May" year="2017"/>
<abstract>
<t>RFC 2119 specifies common key words that may be used in protoco
l specifications. This document aims to reduce the ambiguity by clarifying that
only UPPERCASE usage of the key words have the defined special meanings.</t>
</abstract>
</front>
<seriesInfo name="BCP" value="14"/>
<seriesInfo name="RFC" value="8174"/>
<seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>
</references> </references>
<references anchor="sec-informative-references"> <references anchor="sec-informative-references">
<name>Informative References</name> <name>Informative References</name>
<reference anchor="COMPARISON" target="https://cburgmer.github.io/json-p ath-comparison/"> <reference anchor="COMPARISON" target="https://cburgmer.github.io/json-p ath-comparison/">
<front> <front>
<title>JSONPath Comparison</title> <title>JSONPath Comparison</title>
<author initials="C." surname="Burgmer" fullname="Christoph Burgmer" > <author initials="C." surname="Burgmer" fullname="Christoph Burgmer" >
<organization>Thoughtworks</organization> <organization>Thoughtworks</organization>
</author> </author>
<date>n.d.</date>
</front> </front>
</reference> </reference>
<reference anchor="RFC6901">
<front> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6901.xml"
<title>JavaScript Object Notation (JSON) Pointer</title> />
<author fullname="P. Bryan" initials="P." role="editor" surname="Bry
an"/>
<author fullname="K. Zyp" initials="K." surname="Zyp"/>
<author fullname="M. Nottingham" initials="M." role="editor" surname
="Nottingham"/>
<date month="April" year="2013"/>
<abstract>
<t>JSON Pointer defines a string syntax for identifying a specific
value within a JavaScript Object Notation (JSON) document.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="6901"/>
<seriesInfo name="DOI" value="10.17487/RFC6901"/>
</reference>
<reference anchor="JSONPath-orig" target="https://goessner.net/articles/ JsonPath/"> <reference anchor="JSONPath-orig" target="https://goessner.net/articles/ JsonPath/">
<front> <front>
<title>JSONPath XPath for JSON</title> <title>JSONPath - XPath for JSON</title>
<author initials="S." surname="Gössner" fullname="Stefan Gössner"> <author initials="S." surname="Gössner" fullname="Stefan Gössner">
<organization>Fachhochschule Dortmund</organization> <organization>Fachhochschule Dortmund</organization>
</author> </author>
<date year="2007" month="February" day="21"/> <date year="2007" month="February"/>
</front> </front>
</reference> </reference>
<reference anchor="XPath" target="https://www.w3.org/TR/2010/REC-xpath20 -20101214/"> <reference anchor="XPath" target="https://www.w3.org/TR/2010/REC-xpath20 -20101214/">
<front> <front>
<title>XML Path Language (XPath) 2.0 (Second Edition)</title> <title>XML Path Language (XPath) 2.0 (Second Edition)</title>
<author fullname="Anders Berglund" role="editor"/> <author fullname="Anders Berglund" role="editor"/>
<author fullname="Don Chamberlin" role="editor"/> <author fullname="Don Chamberlin" role="editor"/>
<author fullname="Jerome Simeon" role="editor"/> <author fullname="Jerome Simeon" role="editor"/>
<author fullname="Jonathan Robie" role="editor"/> <author fullname="Jonathan Robie" role="editor"/>
<author fullname="Mary Fernandez" role="editor"/> <author fullname="Mary Fernandez" role="editor"/>
<author fullname="Michael Kay" role="editor"/> <author fullname="Michael Kay" role="editor"/>
<author fullname="Scott Boag" role="editor"/> <author fullname="Scott Boag" role="editor"/>
<date day="14" month="December" year="2010"/> <date day="14" month="December" year="2010"/>
</front> </front>
<seriesInfo name="W3C REC" value="REC-xpath20-20101214"/> <seriesInfo name="W3C" value="REC-xpath20-20101214"/>
<seriesInfo name="W3C" value="REC-xpath20-20101214"/>
</reference> </reference>
<reference anchor="E4X">
<reference anchor="E4X" target="https://www.iso.org/standard/41002.html"
>
<front> <front>
<title>Information technology ECMAScript for XML (E4X) specificati on</title> <title>Information technology - ECMAScript for XML (E4X) specificati on</title>
<author> <author>
<organization>ISO</organization> <organization>ISO</organization>
</author> </author>
<date year="2006"/> <date year="2006" month="February"/>
</front> </front>
<seriesInfo name="ISO/IEC 22537:2006" value=""/> <seriesInfo name="ISO/IEC" value="22537:2006"/>
<refcontent>Withdrawn</refcontent>
<annotation>An equivalent specification, also withdrawn, is available f
rom <eref target="https://ecma-international.org/publications-and-standards/stan
dards/ecma-357" brackets="angle"/>.</annotation>
</reference> </reference>
<reference anchor="SLICE" target="https://github.com/tc39/proposal-slice -notation"> <reference anchor="SLICE" target="https://github.com/tc39/proposal-slice -notation">
<front> <front>
<title>Slice notation</title> <title>Slice notation</title>
<author> <author>
<organization/> <organization/>
</author> </author>
<date>n.d.</date> <date month="July" year="2022"/>
</front> </front>
<refcontent>commit 82f95b4</refcontent>
</reference> </reference>
<reference anchor="ECMA-262" target="https://www.ecma-international.org/ wp-content/uploads/ECMA-262_3rd_edition_december_1999.pdf"> <reference anchor="ECMA-262" target="https://www.ecma-international.org/ wp-content/uploads/ECMA-262_3rd_edition_december_1999.pdf">
<front> <front>
<title>ECMAScript Language Specification, Standard ECMA-262, Third E dition</title> <title>ECMAScript Language Specification</title>
<author> <author>
<organization>Ecma International</organization> <organization>ECMA International</organization>
</author> </author>
<date year="1999" month="December"/> <date year="1999" month="December"/>
</front> </front>
<refcontent>Standard ECMA-262, Third Edition</refcontent>
</reference> </reference>
<reference anchor="RFC8949">
<front> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8949.xml"
<title>Concise Binary Object Representation (CBOR)</title> />
<author fullname="C. Bormann" initials="C." surname="Bormann"/>
<author fullname="P. Hoffman" initials="P." surname="Hoffman"/> <reference anchor="BOOLEAN-LAWS" target="https://en.wikipedia.org/w/inde
<date month="December" year="2020"/> x.php?title=Boolean_algebra&amp;oldid=1191386550#Laws">
<abstract>
<t>The Concise Binary Object Representation (CBOR) is a data forma
t whose design goals include the possibility of extremely small code size, fairl
y small message size, and extensibility without the need for version negotiation
. These design goals make it different from earlier binary serializations such a
s ASN.1 and MessagePack.</t>
<t>This document obsoletes RFC 7049, providing editorial improveme
nts, new details, and errata fixes while keeping full compatibility with the int
erchange format of RFC 7049. It does not create a new version of the format.</t>
</abstract>
</front>
<seriesInfo name="STD" value="94"/>
<seriesInfo name="RFC" value="8949"/>
<seriesInfo name="DOI" value="10.17487/RFC8949"/>
</reference>
<reference anchor="BOOLEAN-LAWS" target="https://en.wikipedia.org/wiki/B
oolean_algebra#Laws">
<front> <front>
<title>Boolean algebra laws</title> <title>Boolean algebra: Laws</title>
<author> <author>
<organization/> <organization/>
</author> </author>
<date>n.d.</date> <date month="December" year="2023"/>
</front> </front>
</reference> </reference>
</references> </references>
</references> </references>
<?line 2296?>
<section anchor="collected-abnf-grammars"> <section anchor="collected-abnf-grammars">
<name>Collected ABNF grammars</name> <name>Collected ABNF Grammars</name>
<t>This appendix collects the ABNF grammar from the ABNF passages used <t>This appendix collects the ABNF grammar from the ABNF passages used
throughout the document.</t> throughout the document.</t>
<!-- Update the collected grammar files using `make sourcecode`, which -->
<!-- is currently manual as it creates a little circular dependency. -->
<!-- The filenames of the ::includes are likely to change when -->
<!-- kramdown-rfc-extract-sourcecode handles filenames better. -->
<t><xref target="jsonpath-abnf"/> contains the collected ABNF grammar that defin es the <t><xref target="jsonpath-abnf"/> contains the collected ABNF grammar that defin es the
syntax of a JSONPath query.</t> syntax of a JSONPath query.</t>
<figure anchor="jsonpath-abnf"> <figure anchor="jsonpath-abnf">
<name>Collected ABNF of JSONPath queries</name> <name>Collected ABNF of JSONPath Queries</name>
<sourcecode type="abnf"><![CDATA[ <sourcecode type="abnf"><![CDATA[
jsonpath-query = root-identifier segments jsonpath-query = root-identifier segments
segments = *(S segment) segments = *(S segment)
B = %x20 / ; Space B = %x20 / ; Space
%x09 / ; Horizontal tab %x09 / ; Horizontal tab
%x0A / ; Line feed or New line %x0A / ; Line feed or New line
%x0D ; Carriage return %x0D ; Carriage return
S = *B ; optional blank space S = *B ; optional blank space
root-identifier = "$" root-identifier = "$"
selector = name-selector / selector = name-selector /
wildcard-selector / wildcard-selector /
slice-selector / slice-selector /
index-selector / index-selector /
filter-selector filter-selector
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 /
%x27 / ; ' %x27 / ; '
ESC %x22 / ; \" ESC %x22 / ; \"
ESC escapable ESC escapable
single-quoted = unescaped / single-quoted = unescaped /
%x22 / ; " %x22 / ; "
ESC %x27 / ; \' ESC %x27 / ; \'
ESC escapable ESC escapable
ESC = %x5C ; \ backslash ESC = %x5C ; \ backslash
unescaped = %x20-21 / ; see RFC 8259 unescaped = %x20-21 / ; see RFC 8259
; omit 0x22 " ; omit 0x22 "
%x23-26 / %x23-26 /
; omit 0x27 ' ; omit 0x27 '
%x28-5B / %x28-5B /
; omit 0x5C \ ; omit 0x5C \
%x5D-D7FF / ; skip surrogate code points %x5D-D7FF /
; skip surrogate code points
%xE000-10FFFF %xE000-10FFFF
escapable = %x62 / ; b BS backspace U+0008 escapable = %x62 / ; b BS backspace U+0008
%x66 / ; f FF form feed U+000C %x66 / ; f FF form feed U+000C
%x6E / ; n LF line feed U+000A %x6E / ; n LF line feed U+000A
%x72 / ; r CR carriage return U+000D %x72 / ; r CR carriage return U+000D
%x74 / ; t HT horizontal tab U+0009 %x74 / ; t HT horizontal tab U+0009
"/" / ; / slash (solidus) U+002F "/" / ; / slash (solidus) U+002F
"\" / ; \ backslash (reverse solidus) U+005C "\" / ; \ backslash (reverse solidus) U+005C
(%x75 hexchar) ; uXXXX U+XXXX (%x75 hexchar) ; uXXXX U+XXXX
hexchar = non-surrogate / hexchar = non-surrogate /
(high-surrogate "\" %x75 low-surrogate) (high-surrogate "\" %x75 low-surrogate)
non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) /
("D" %x30-37 2HEXDIG ) ("D" %x30-37 2HEXDIG )
high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG
low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
wildcard-selector = "*" wildcard-selector = "*"
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
skipping to change at line 3546 skipping to change at line 3367
; binds more tightly than disjunction ; binds more tightly than disjunction
basic-expr = paren-expr / basic-expr = paren-expr /
comparison-expr / comparison-expr /
test-expr test-expr
paren-expr = [logical-not-op S] "(" S logical-expr S ")" paren-expr = [logical-not-op S] "(" S logical-expr S ")"
; parenthesized expression ; parenthesized expression
logical-not-op = "!" ; logical NOT operator logical-not-op = "!" ; logical NOT operator
test-expr = [logical-not-op S] test-expr = [logical-not-op S]
(filter-query / ; existence/non-existence (filter-query / ; existence/non-existence
function-expr) ; LogicalType or NodesType function-expr) ; LogicalType or NodesType
filter-query = rel-query / jsonpath-query filter-query = rel-query / jsonpath-query
rel-query = current-node-identifier segments rel-query = current-node-identifier segments
current-node-identifier = "@" current-node-identifier = "@"
comparison-expr = comparable S comparison-op S comparable comparison-expr = comparable S comparison-op S comparable
literal = number / string-literal / literal = number / string-literal /
true / false / null true / false / null
comparable = literal / comparable = literal /
singular-query / ; singular query value singular-query / ; singular query value
function-expr ; ValueType function-expr ; ValueType
comparison-op = "==" / "!=" / comparison-op = "==" / "!=" /
skipping to change at line 3596 skipping to change at line 3417
child-segment = bracketed-selection / child-segment = bracketed-selection /
("." ("."
(wildcard-selector / (wildcard-selector /
member-name-shorthand)) member-name-shorthand))
bracketed-selection = "[" S selector *(S "," S selector) S "]" bracketed-selection = "[" S selector *(S "," S selector) S "]"
member-name-shorthand = name-first *name-char member-name-shorthand = name-first *name-char
name-first = ALPHA / name-first = ALPHA /
"_" / "_" /
%x80-D7FF / ; skip surrogate code points %x80-D7FF /
; skip surrogate code points
%xE000-10FFFF %xE000-10FFFF
name-char = DIGIT / name-first name-char = name-first / DIGIT
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
descendant-segment = ".." (bracketed-selection / descendant-segment = ".." (bracketed-selection /
wildcard-selector / wildcard-selector /
member-name-shorthand) member-name-shorthand)
]]></sourcecode> ]]></sourcecode>
</figure> </figure>
<t><xref target="normalized-path-abnf"/> contains the collected ABNF gramm ar that <t><xref target="normalized-path-abnf"/> contains the collected ABNF gramm ar that
defines the syntax of a JSONPath Normalized Path, while also using the rules defines the syntax of a JSONPath Normalized Path while also using the rules
<tt>root-identifier</tt>, <tt>ESC</tt>, <tt>DIGIT</tt>, and <tt>DIGIT1</tt> from <xref target="jsonpath-abnf"/>.</t> <tt>root-identifier</tt>, <tt>ESC</tt>, <tt>DIGIT</tt>, and <tt>DIGIT1</tt> from <xref target="jsonpath-abnf"/>.</t>
<figure anchor="normalized-path-abnf"> <figure anchor="normalized-path-abnf">
<name>Collected ABNF of JSONPath Normalized Paths</name> <name>Collected ABNF of JSONPath Normalized Paths</name>
<sourcecode type="abnf"><![CDATA[ <sourcecode type="abnf"><![CDATA[
normalized-path = root-identifier *(normal-index-segment) normalized-path = root-identifier *(normal-index-segment)
normal-index-segment = "[" normal-selector "]" normal-index-segment = "[" normal-selector "]"
normal-selector = normal-name-selector / normal-index-selector normal-selector = normal-name-selector / normal-index-selector
normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string'
normal-single-quoted = normal-unescaped / normal-single-quoted = normal-unescaped /
ESC normal-escapable ESC normal-escapable
normal-unescaped = ; omit %x0-1F control codes normal-unescaped = ; omit %x0-1F control codes
%x20-26 / %x20-26 /
; omit 0x27 ' ; omit 0x27 '
%x28-5B / %x28-5B /
; omit 0x5C \ ; omit 0x5C \
%x5D-D7FF / ; skip surrogate code points %x5D-D7FF /
; skip surrogate code points
%xE000-10FFFF %xE000-10FFFF
normal-escapable = %x62 / ; b BS backspace U+0008 normal-escapable = %x62 / ; b BS backspace U+0008
%x66 / ; f FF form feed U+000C %x66 / ; f FF form feed U+000C
%x6E / ; n LF line feed U+000A %x6E / ; n LF line feed U+000A
%x72 / ; r CR carriage return U+000D %x72 / ; r CR carriage return U+000D
%x74 / ; t HT horizontal tab U+0009 %x74 / ; t HT horizontal tab U+0009
"'" / ; ' apostrophe U+0027 "'" / ; ' apostrophe U+0027
"\" / ; \ backslash (reverse solidus) U+005C "\" / ; \ backslash (reverse solidus) U+005C
(%x75 normal-hexchar) (%x75 normal-hexchar)
; certain values u00xx U+00XX ; certain values u00xx U+00XX
normal-hexchar = "0" "0" normal-hexchar = "0" "0"
( (
("0" %x30-37) / ; "00"-"07" ("0" %x30-37) / ; "00"-"07"
; omit U+0008-U+000A BS HT LF ; omit U+0008-U+000A BS HT LF
("0" %x62) / ; "0b" ("0" %x62) / ; "0b"
; omit U+000C-U+000D FF CR ; omit U+000C-U+000D FF CR
("0" %x65-66) / ; "0e"-"0f" ("0" %x65-66) / ; "0e"-"0f"
("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-index-selector = "0" / (DIGIT1 *DIGIT) normal-index-selector = "0" / (DIGIT1 *DIGIT)
; non-negative decimal integer ; non-negative decimal integer
]]></sourcecode> ]]></sourcecode>
</figure> </figure>
</section> </section>
<section anchor="inspired-by-xpath"> <section anchor="inspired-by-xpath">
<name>Inspired by XPath</name> <name>Inspired by XPath</name>
<t>This appendix is informative.</t> <t>This appendix is informative.</t>
<t>At the time JSONPath was invented, XML was noted for the availability o f <t>At the time JSONPath was invented, XML was noted for the availability o f
powerful tools to analyze, transform and selectively extract data from powerful tools to analyze, transform, and selectively extract data from
XML documents. XML documents.
<xref target="XPath"/> is one of these tools.</t> <xref target="XPath"/> is one of these tools.</t>
<t>In 2007, the need for something solving the same class of problems for <t>In 2007, the need for something solving the same class of problems for
the emerging JSON community became apparent, specifically for:</t> the emerging JSON community became apparent, specifically for:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>Finding data interactively and extracting them out of <xref target=" <li>finding data interactively and extracting them out of
RFC8259"/> JSON values <xref target="RFC8259"/> without special scripting and</li>
JSON values without special scripting.</li> <li>specifying the relevant parts of the JSON data in a request by a
<li>Specifying the relevant parts of the JSON data in a request by a
client, so the server can reduce the amount of data in its response, client, so the server can reduce the amount of data in its response,
minimizing bandwidth usage.</li> minimizing bandwidth usage.</li>
</ul> </ul>
<t>(Note: XPath has evolved since 2007, and recent versions even <t>(Note: XPath has evolved since 2007, and recent versions even
nominally support operating inside JSON values. nominally support operating inside JSON values.
This appendix only discusses the more widely used version of XPath This appendix only discusses the more widely used version of XPath
that was available in 2007.)</t> that was available in 2007.)</t>
<t>JSONPath picks up the overall feeling of XPath, but maps the concepts <t>JSONPath picks up the overall feeling of XPath but maps the concepts
to syntax (and partially semantics) that would be familiar to someone to syntax (and partially semantics) that would be familiar to someone
using JSON in a dynamic language.</t> using JSON in a dynamic language.</t>
<t>E.g., in popular dynamic programming languages such as JavaScript, <t>For example, in popular dynamic programming languages such as JavaScrip
Python and PHP, the semantics of the XPath expression</t> t,
Python, and PHP, the semantics of the XPath expression:</t>
<sourcecode type="xpath"><![CDATA[ <sourcecode type="xpath"><![CDATA[
/store/book[1]/title /store/book[1]/title
]]></sourcecode> ]]></sourcecode>
<t>can be realized in the expression</t> <t>can be realized in the expression:</t>
<sourcecode type="xpath"><![CDATA[ <sourcecode type="xpath"><![CDATA[
x.store.book[0].title x.store.book[0].title
]]></sourcecode> ]]></sourcecode>
<t>or, in bracket notation,</t> <t>or in bracket notation:</t>
<sourcecode type="xpath"><![CDATA[ <sourcecode type="xpath"><![CDATA[
x['store']['book'][0]['title'] x['store']['book'][0]['title']
]]></sourcecode> ]]></sourcecode>
<t>with the variable x holding the query argument.</t> <t>with the variable x holding the query argument.</t>
<t>The JSONPath language was designed to:</t> <t>The JSONPath language was designed to:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>be naturally based on those language characteristics;</li> <li>be naturally based on those language characteristics,</li>
<li>cover only the most essential parts of XPath 1.0;</li> <li>cover only the most essential parts of XPath 1.0,</li>
<li>be lightweight in code size and memory consumption;</li> <li>be lightweight in code size and memory consumption, and</li>
<li>be runtime efficient.</li> <li>be runtime efficient.</li>
</ul> </ul>
<section anchor="xpath-overview"> <section anchor="xpath-overview">
<name>JSONPath and XPath</name> <name>JSONPath and XPath</name>
<t>JSONPath expressions apply to JSON values in the same way <t>JSONPath expressions apply to JSON values in the same way
as XPath expressions are used in combination with an XML document. as XPath expressions are used in combination with an XML document.
JSONPath uses <tt>$</tt> to refer to the root node of the query argument, simila r JSONPath uses <tt>$</tt> to refer to the root node of the query argument, simila r
to XPath's <tt>/</tt> at the front.</t> to XPath's <tt>/</tt> at the front.</t>
<t>JSONPath expressions move further down the hierarchy using <em>dot no tation</em> <t>JSONPath expressions move further down the hierarchy using <em>dot notation</ em>
(<tt>$.store.book[0].title</tt>) (<tt>$.store.book[0].title</tt>)
or the <em>bracket notation</em> or the <em>bracket notation</em>
(<tt>$['store']['book'][0]['title']</tt>), a lightweight/limited, and a more (<tt>$['store']['book'][0]['title']</tt>); both replace XPath's <tt>/</tt> withi
heavyweight syntax replacing XPath's <tt>/</tt> within query expressions.</t> n query expressions, where <em>dot notation</em> serves as a lightweight but lim
ited syntax while <em>bracket notation</em> is a
heavyweight but more general syntax.</t>
<t>Both JSONPath and XPath use <tt>*</tt> for a wildcard. <t>Both JSONPath and XPath use <tt>*</tt> for a wildcard.
The descendant operators, starting with <tt>..</tt>, borrowed from <xref target= "E4X"/>, are similar to XPath's <tt>//</tt>. JSONPath's descendant segment notation, starting with <tt>..</tt>, borrowed from <xref target="E4X"/>, is similar to XPath's <tt>//</tt>.
The array slicing construct <tt>[start:end:step]</tt> is unique to JSONPath, The array slicing construct <tt>[start:end:step]</tt> is unique to JSONPath,
inspired by <xref target="SLICE"/> from ECMASCRIPT 4.</t> inspired by <xref target="SLICE"/> from ECMASCRIPT 4.</t>
<t>Filter expressions are supported via the syntax <tt>?&lt;logical-expr <t>Filter expressions are supported via the syntax <tt>?&lt;logical-expr
&gt;</tt> as in</t> &gt;</tt> as in:</t>
<sourcecode type="JSONPath"><![CDATA[ <sourcecode type="application/jsonpath"><![CDATA[
$.store.book[?@.price < 10].title $.store.book[?@.price < 10].title
]]></sourcecode> ]]></sourcecode>
<t><xref target="tbl-xpath-overview"/> extends <xref target="tbl-overvie w"/> by providing a comparison <t><xref target="tbl-xpath-overview"/> extends <xref target="tbl-overvie w"/> by providing a comparison
with similar XPath concepts.</t> with similar XPath concepts.</t>
<table anchor="tbl-xpath-overview"> <table anchor="tbl-xpath-overview">
<name>XPath syntax compared to JSONPath</name> <name>XPath Syntax Compared to JSONPath</name>
<thead> <thead>
<tr> <tr>
<th align="left">XPath</th> <th align="left">XPath</th>
<th align="left">JSONPath</th> <th align="left">JSONPath</th>
<th align="left">Description</th> <th align="left">Description</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left"> <td align="left">
skipping to change at line 3757 skipping to change at line 3580
<tr> <tr>
<td align="left"> <td align="left">
<tt>..</tt></td> <tt>..</tt></td>
<td align="left">n/a</td> <td align="left">n/a</td>
<td align="left">parent operator</td> <td align="left">parent operator</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>//</tt></td> <tt>//</tt></td>
<td align="left"> <td align="left">
<tt>..name</tt>, <tt>..[index]</tt>, <tt>..*</tt>, or <tt>..[*]< /tt></td> <tt>..name</tt>, <tt>..&wj;[index]</tt>, <tt>..*</tt>, or <tt>.. [*]</tt></td>
<td align="left">descendants (JSONPath borrows this syntax from E4 X)</td> <td align="left">descendants (JSONPath borrows this syntax from E4 X)</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>*</tt></td> <tt>*</tt></td>
<td align="left"> <td align="left">
<tt>*</tt></td> <tt>*</tt></td>
<td align="left">wildcard: All XML elements regardless of their na mes</td> <td align="left">wildcard: All XML elements regardless of their na mes</td>
</tr> </tr>
<tr> <tr>
skipping to change at line 3813 skipping to change at line 3636
<td align="left">expression engine</td> <td align="left">expression engine</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>()</tt></td> <tt>()</tt></td>
<td align="left">n/a</td> <td align="left">n/a</td>
<td align="left">grouping</td> <td align="left">grouping</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<!-- Note: the weirdness about the vertical bar above is intentional -->
<t>For further illustration, <xref target="tbl-xpath-equivalents"/> shows some X Path expressions <t>For further illustration, <xref target="tbl-xpath-equivalents"/> shows some X Path expressions
and their JSONPath equivalents.</t> and their JSONPath equivalents.</t>
<table anchor="tbl-xpath-equivalents"> <table anchor="tbl-xpath-equivalents">
<name>Example XPath expressions and their JSONPath equivalents</name> <name>Example XPath Expressions and Their JSONPath Equivalents</name>
<thead> <thead>
<tr> <tr>
<th align="left">XPath</th> <th align="left">XPath</th>
<th align="left">JSONPath</th> <th align="left">JSONPath</th>
<th align="left">Result</th> <th align="left">Result</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td align="left"> <td align="left">
skipping to change at line 3871 skipping to change at line 3692
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>//book[last()]</tt></td> <tt>//book[last()]</tt></td>
<td align="left"> <td align="left">
<tt>$..book[-1]</tt></td> <tt>$..book[-1]</tt></td>
<td align="left">the last book in order</td> <td align="left">the last book in order</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>//book[position()&lt;3]</tt></td> <tt>//&wj;book[position()&lt;3]</tt></td>
<td align="left"> <td align="left">
<tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> <tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td>
<td align="left">the first two books</td> <td align="left">the first two books</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>//book[isbn]</tt></td> <tt>//book[isbn]</tt></td>
<td align="left"> <td align="left">
<tt>$..book[?@.isbn]</tt></td> <tt>$..book[?@.isbn]</tt></td>
<td align="left">filter all books with isbn number</td> <td align="left">filter all books with an ISBN number</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>//book[price&lt;10]</tt></td> <tt>//book[price&lt;10]</tt></td>
<td align="left"> <td align="left">
<tt>$..book[?@.price&lt;10]</tt></td> <tt>$..book[?@.price&lt;10]</tt></td>
<td align="left">filter all books cheaper than 10</td> <td align="left">filter all books cheaper than 10</td>
</tr> </tr>
<tr> <tr>
<td align="left"> <td align="left">
<tt>//*</tt></td> <tt>//*</tt></td>
<td align="left"> <td align="left">
<tt>$..*</tt></td> <tt>$..*</tt></td>
<td align="left">all elements in XML document; all member values a nd array elements contained in input value</td> <td align="left">all elements in an XML document; all member value s and array elements contained in input value</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<t>XPath has a lot more functionality (location paths in unabbreviated s yntax, <t>XPath has a lot more functionality (location paths in unabbreviated s yntax,
operators and functions) than listed in this comparison. Moreover, there are operators, and functions) than listed in this comparison. Moreover, there are
significant differences in how the subscript operator works in XPath and significant differences in how the subscript operator works in XPath and
JSONPath:</t> JSONPath:</t>
<ul spacing="normal"> <ul spacing="normal">
<li>Square brackets in XPath expressions always operate on the <em>nod e <li>Square brackets in XPath expressions always operate on the <em>nod e
set</em> resulting from the previous path fragment. Indices always start set</em> resulting from the previous path fragment. Indices always start
at 1.</li> at 1.</li>
<li>With JSONPath, square brackets operate on each of the nodes in the <em>nodelist</em> <li>With JSONPath, square brackets operate on each of the nodes in the <em>nodelist</em>
resulting from the previous query segment. Array indices always start resulting from the previous query segment. Array indices always start
at 0.</li> at 0.</li>
</ul> </ul>
</section> </section>
</section> </section>
<section anchor="json-pointer"> <section anchor="json-pointer">
<name>JSON Pointer</name> <name>JSON Pointer</name>
<t>This appendix is informative.</t> <t>This appendix is informative.</t>
<t>JSONPath is not intended as a replacement for, but as a more powerful <t>In relation to JSON Pointer <xref target="RFC6901"/>, JSONPath is not i
companion to, JSON Pointer <xref target="RFC6901"/>. The purposes of the two sta ntended as a replacement but as a more powerful
ndards companion. The purposes of the two standards
are different.</t> are different.</t>
<t>JSON Pointer is for identifying a single value within a JSON value whos e <t>JSON Pointer is for identifying a single value within a JSON value whos e
structure is known.</t> structure is known.</t>
<t>JSONPath can identify a single value within a JSON value, for example b y <t>JSONPath can identify a single value within a JSON value, for example, by
using a Normalized Path. But JSONPath is also a query syntax that can be used using a Normalized Path. But JSONPath is also a query syntax that can be used
to search for and extract multiple values from JSON values whose structure to search for and extract multiple values from JSON values whose structure
is known only in a general way.</t> is known only in a general way.</t>
<t>A Normalized JSONPath can be converted into a JSON Pointer by convertin g the syntax, <t>A Normalized JSONPath can be converted into a JSON Pointer by convertin g the syntax,
without knowledge of any JSON value. The inverse is not generally true: a numeri c without knowledge of any JSON value. The inverse is not generally true, i.e., a numeric
reference token (path component) in a JSON Pointer may identify a member value o f an object or an element of an array. reference token (path component) in a JSON Pointer may identify a member value o f an object or an element of an array.
For conversion to a JSONPath query, knowledge of the structure of the JSON value is For conversion to a JSONPath query, knowledge of the structure of the JSON value is
needed to distinguish these cases.</t> needed to distinguish these cases.</t>
</section> </section>
<section numbered="false" anchor="acknowledgements"> <section numbered="false" anchor="acknowledgements">
<name>Acknowledgements</name> <name>Acknowledgements</name>
<t>This document is based on <contact fullname="Stefan Gössner"/>'s <t>This document is based on <contact fullname="Stefan Gössner"/>'s
original online article defining JSONPath <xref target="JSONPath-orig"/>.</t> original online article defining JSONPath <xref target="JSONPath-orig"/>.</t>
<t>The books example was taken from <t>The books example was taken from course material that Bielefeld University, G
http://coli.lili.uni-bielefeld.de/~andreas/Seminare/sommer02/books.xml ermany used in 2002.</t>
— a dead link now.</t> <t>This work is indebted to <contact fullname="Christoph Burgmer"/> for th
<t>This work is indebted to Christoph Burgmer for the superb e superb
JSONPath comparison project <xref target="COMPARISON"/> detailing the behavior o JSONPath comparison project <xref target="COMPARISON"/> that details the behavio
f over forty JSONPath r of over forty JSONPath
implementations applied to numerous queries.</t> implementations applied to numerous queries.</t>
<!-- LocalWords: JSONPath XPath nodelist memoization
-->
</section> </section>
<section anchor="contributors" numbered="false" toc="include" removeInRFC="f alse"> <section anchor="contributors" numbered="false" toc="include">
<name>Contributors</name> <name>Contributors</name>
<contact initials="M." surname="Mikulicic" fullname="Marko Mikulicic"> <contact initials="M." surname="Mikulicic" fullname="Marko Mikulicic">
<organization>InfluxData, Inc.</organization> <organization>InfluxData, Inc.</organization>
<address> <address>
<postal> <postal>
<city>Pisa</city> <city>Pisa</city>
<country>IT</country> <country>Italy</country>
</postal> </postal>
<email>mmikulicic@gmail.com</email> <email>mmikulicic@gmail.com</email>
</address> </address>
</contact> </contact>
<contact initials="E." surname="Surov" fullname="Edward Surov"> <contact initials="E." surname="Surov" fullname="Edward Surov">
<organization>TheSoul Publishing Ltd.</organization> <organization>TheSoul Publishing Ltd.</organization>
<address> <address>
<postal> <postal>
<city>Limassol</city> <city>Limassol</city>
<country>Cyprus</country> <country>Cyprus</country>
skipping to change at line 3980 skipping to change at line 3796
<postal> <postal>
<city>Auckland</city> <city>Auckland</city>
<country>New Zealand</country> <country>New Zealand</country>
</postal> </postal>
<email>gregsdennis@yahoo.com</email> <email>gregsdennis@yahoo.com</email>
<uri>https://github.com/gregsdennis</uri> <uri>https://github.com/gregsdennis</uri>
</address> </address>
</contact> </contact>
</section> </section>
</back> </back>
<!-- ##markdown-source:
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
AA==
</rfc> </rfc>
 End of changes. 311 change blocks. 
1506 lines changed or deleted 562 lines changed or added

This html diff was produced by rfcdiff 1.48.