<?xmlversion='1.0' encoding='utf-8'?>version="1.0" encoding="UTF-8"?> <!DOCTYPE rfc [ <!ENTITY nbsp " "> <!ENTITY zwsp "​"> <!ENTITY nbhy "‑"> <!ENTITY wj "⁠"> ]><?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?><!-- 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-ietf-jsonpath-base-21" number="9535" submissionType="IETF" category="std" consensus="true"submissionType="IETF"xml:lang="en" tocDepth="4" tocInclude="true" sortRefs="true" symRefs="true" updates="" obsoletes="" version="3"> <!-- xml2rfc v2v3 conversion 3.18.0 --> <front> <title abbrev="JSONPath">JSONPath: QueryexpressionsExpressions for JSON</title> <seriesInfoname="Internet-Draft" value="draft-ietf-jsonpath-base-21"/>name="RFC" value="9535"/> <author initials="S." surname="Gössner" fullname="Stefan Gössner" role="editor"> <organization>Fachhochschule Dortmund</organization> <address> <postal> <street>Sonnenstraße 96</street> <city>Dortmund</city> <code>D-44139</code> <country>Germany</country> </postal> <email>stefan.goessner@fh-dortmund.de</email> </address> </author> <author initials="G." surname="Normington" fullname="Glyn Normington" role="editor"> <organization/> <address> <postal> <street/> <city>Winchester</city> <region/> <code/><country>UK</country><country>United Kingdom</country> </postal> <phone/> <email>glyn.normington@gmail.com</email> </address> </author> <author initials="C." surname="Bormann" fullname="Carsten Bormann" role="editor"> <organization>Universität Bremen TZI</organization> <address> <postal> <street>Postfach 330440</street> <city>Bremen</city> <code>D-28359</code> <country>Germany</country> </postal> <phone>+49-421-218-63921</phone> <email>cabo@tzi.org</email> </address> </author> <dateyear="2023"/> <area>ART</area> <workgroup>JSONPath WG</workgroup>year="2024" month="February"/> <area>art</area> <workgroup>jsonpath</workgroup> <keyword>JSON</keyword> <abstract><?line 145?><t>JSONPath defines a string syntax for selecting and extracting JSON (RFC 8259) values from within a given JSON value.</t> </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/browse/jsonpath/"/>. Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/jsonpath/"/>. </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-base"/>.</t> </note></front> <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"> <name>Introduction</name> <t>JSON <xref target="RFC8259"/> is a popular representation format for structured data values. JSONPath defines a string syntax for selecting and extracting JSON values from within a given JSON value.</t><t>JSONPath<t>In relation to JSON Pointer <xref target="RFC6901"/>, JSONPath is not intended as a replacementfor,but as a more powerfulcompanion to, JSON Pointer <xref target="RFC6901"/>.companion. See <xref target="json-pointer"/>.</t> <section anchor="terminology"> <name>Terminology</name><t>The<t> The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described inBCP 14BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shownhere.</t> <?line -18?>here. </t> <t>The grammatical rules in this document are to be interpreted as ABNF, as described in <xref target="RFC5234"/>. ABNF terminal values in this document define Unicode scalar values rather than their UTF-8 encoding. For example, the Unicode PLACE OF INTEREST SIGN (U+2318) would be defined in ABNF as <tt>%x2318</tt>.</t> <t>Functions are referred to using the function name followed by a pair of parentheses, as in <tt>fname()</tt>.</t> <t>The terminology of <xref target="RFC8259"/> applies except where clarified below. The terms"Primitive""primitive" and"Structured""structured" are used to group different kinds of values as in <xref section="1" sectionFormat="of"target="RFC8259"/>;target="RFC8259"/>. JSONObjectsobjects andArraysarrays arestructured,structured; all other values are primitive. Definitions for"Object", "Array", "Number","object", "array", "number", and"String""string" remain unchanged.ImportantlyImportantly, "object" and "array" in particular do not take on a generic meaning, such as they would in a general programming context.</t> <t>The terminology of <xref target="RFC9485"/> applies.</t> <t>Additional terms used in this document are defined below.</t> <dl> <dt>Value:</dt> <dd> <t>As per <xref target="RFC8259"/>, astructuredata item conforming to the generic data model of JSON, i.e.,composed of constituents such as structured values, namely JSON objects and arrays, andprimitivedata, namely numbers anddata (numbers, textstrings as well asstrings, and the special values null, true, andfalse.false), or structured data (JSON objects and arrays). <xref target="RFC8259"/> focuses on the textual representation of JSON values and does not fully define the value abstraction assumed here.</t> </dd> <dt>Member:</dt> <dd> <t>A name/value pair in an object. (A member is not itself a value.)</t> </dd> <dt>Name:</dt> <dd> <t>The name (a string) in a name/value pair constituting a member. This is also used in <xref target="RFC8259"/>, but that specification does not formally define it. It is included here for completeness.</t> </dd> <dt>Element:</dt> <dd> <t>A value in a JSON array.</t> </dd> <dt>Index:</dt> <dd> <t>An integer that identifies a specific element in an array.</t> </dd> <dt>Query:</dt> <dd> <t>Short name for a JSONPath expression.</t> </dd> <dt>Query Argument:</dt> <dd> <t>Short name for the value a JSONPath expression is applied to.(Also used for actual parameters of function-expressions.)</t></t> </dd> <dt>Location:</dt> <dd><t>the<t>The position of a value within the query argument. This can be thought of as a sequence of names and indexes navigating to the value through the objects and arrays in the query argument, with the empty sequence indicating the query argument itself. A location can be represented as a Normalized Path (defined below).</t> </dd> <dt>Node:</dt> <dd> <t>The pair of a value along with its location within the query argument.</t> </dd> <dt>Root Node:</dt> <dd> <t>The unique node whose value is the entire query argument.</t> </dd> <dt>Root Node Identifier:</dt> <dd> <t>The expression<tt>$</tt><tt>$</tt>, which refers to the root node of the query argument.</t> </dd> <dt>Current Node Identifier:</dt> <dd> <t>The expression<tt>@</tt><tt>@</tt>, which refers to the current node in the context of the evaluation of a filter expression (described later).</t> </dd> <dt>Children (of a node):</dt> <dd> <t>If the node is an array, the nodes of itselements. Ifelements; if the node is an object, the nodes of its member values. If the node is neither an array nor an object, it has no children.</t> </dd> <dt>Descendants (of a node):</dt> <dd> <t>The children of the node, together with the children of its children, and so forth recursively. More formally, the "descendants" relation between nodes is the transitive closure of the "children" relation.</t> </dd> <dt>Depth (of a descendant node within a value):</dt> <dd> <t>The number of ancestors of the node within the value. The root node of the value has depth zero, the children of the root node have depth one, their children have depth two, and so forth.</t> </dd> <dt>Nodelist:</dt> <dd> <t>A list of nodes. While a nodelist can be represented in JSON,e.g.e.g., as an array, this document does not require or assume any particular representation.</t> </dd> <dt>Parameter:</dt> <dd> <t>Formal parameter (of a function) that can take a function argument (an actual parameter) in afunction-expression.</t>function expression.</t> </dd> <dt>Normalized Path:</dt> <dd> <t>A form of JSONPath expression that identifies a node in a value by providing a query that results in exactly that node. Each node in a query argument is identified by exactly one Normalized Path (wesay,say that the Normalized Path is "unique" for that node),and,and to be a Normalized Path for a specific query argument, the Normalized Path needs to identify exactly one node.SimilarThis is similar to, but syntactically different from, a JSON Pointer <xref target="RFC6901"/>. Note: This definition is based on the syntactical definition in <xref target="normalized-paths"/>; JSONPath expressions that identify a node in a value but do not conform to that syntax are not Normalized Paths.</t> </dd> <dt>Unicode Scalar Value:</dt> <dd> <t>Any Unicode <xref target="UNICODE"/> code point except high-surrogate and low-surrogate codepoints. Inpoints (in other words, integers ineither ofthe inclusive base 16rangesranges, either 0 to D7FFandor E000 to10FFFF.10FFFF). JSONPath queries are sequences of Unicode scalar values.</t> </dd> <dt>Segment:</dt> <dd> <t>One of the constructswhich selectthat selects children (<tt>[<selectors>]</tt>) or descendants(<tt>..[<selectors>]</tt>)(<tt>..&wj;[<selectors>]</tt>) of an input value.</t> </dd> <dt>Selector:</dt> <dd> <t>A single item within a segment that takes the input value and produces a nodelist consisting of child nodes of the input value.</t> </dd> <dt>Singular Query:</dt> <dd> <t>A JSONPath expression built from segments that have been syntactically restricted in a certain way (<xref target="filter-selector-syntax"/>) so that, regardless of the input value, the expression produces a nodelist containing at most one node. Note: JSONPath expressions that always produce a singular nodelist but do not conform to the syntax in <xref target="filter-selector-syntax"/> are notSingular Queries.</t>singular queries.</t> </dd> </dl> <section anchor="json-values-as-trees-of-nodes"> <name>JSON Values as Trees of Nodes</name> <t>This document models the query argument as a tree of JSON values, each with its own node. 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 query argument as a nodelist (a list of nodes).</t> <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 member values. Member names and members (name/value pairs) cannot be selected. Thus, member values have nodes, but members and member names do not. Similarly, member values are children of an object, but members and member names are not.</t> </section> </section> <section anchor="history"> <name>History</name> <t>This document is based on <contact fullname="Stefan Gössner"/>'s popular JSONPath proposaldated 2007-02-21(dated 2007-02-21) <xref target="JSONPath-orig"/>, builds on the experience from the widespread deployment of its implementations, and provides a normative specification for it.</t> <t><xref target="inspired-by-xpath"/> describes how JSONPath was inspired by XML's XPath <xref target="XPath"/>.</t> <t>JSONPath was intended as alight-weightlightweight companion to JSON implementations in programming languages such as PHP and JavaScript, so instead of defining its own expression language, like XPath did, JSONPath delegated parts of a query to the underlying runtime, e.g., JavaScript's <tt>eval()</tt> function. As JSONPath was implemented in more environments, JSONPath expressions became decreasingly portable. For example, regular expression processing was often delegated to a convenient regular expression engine.</t> <t>This document aims to remove such implementation-specific dependencies and serve as a common JSONPath specification that can be used across programming languages and environments. This means that backwards compatibility is not always achieved; a design principle of this document is to go with a "consensus" between implementations even if it is rough, as long as that does not jeopardize the objective of obtaining a usable, stable JSON query language.</t> <t>The term <em>JSONPath</em> was chosen because of the XPath inspiration and also because the outcome of a query consists of <em>paths</em> identifying nodes in the JSON query argument.</t> </section> <section anchor="json-values"> <name>JSON Values</name> <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 a JSON text.</t> <t>The parsing of a JSON text into a JSON value and what happens if a JSON text does not represent valid JSON are not defined by this document. Sections <xref target="RFC8259" section="4" sectionFormat="bare"/> and <xref target="RFC8259" section="8" sectionFormat="bare"/> of <xref target="RFC8259"/> identify specific situations that may conform to the grammar for JSON texts but are not interoperable uses of JSON, as they may cause unpredictable behavior. This document does not attempt to define predictable behavior for JSONPath queries in these situations.</t> <t>Specifically, the "Semantics" subsections of Sections <xref format="counter" target="name-selector"/>, <xref format="counter" target="wildcard-selector"/>, <xref format="counter" target="filter-selector"/>, and <xref format="counter" target="descendant-segment"/> describe behavior that becomes unpredictable when the JSON value for one of the objects under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicatenames",names"; see <xref section="4" sectionFormat="of" target="RFC8259"/>). Also, when selecting a child by name (<xref target="name-selector"/>) and comparing strings (<xreftarget="comparisons"/> in <xref target="filter-selector"/>) assumetarget="comparisons"/>), it is assumed these strings are sequences of Unicode scalarvalues, becomingvalues; the behavior becomes unpredictable if they are not (<xref section="8.2" sectionFormat="of" target="RFC8259"/>).</t> </section> <section anchor="overview"> <name>Overview of JSONPath Expressions</name> <t>A JSONPath expression is applied to a JSON value, known as the query argument. The output is a nodelist.</t> <t>A JSONPath expression consists of an identifier followed by a series of zero or moresegmentssegments, each of which contains one or more selectors.</t> <section anchor="ids"> <name>Identifiers</name> <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> <t>The current node identifier <tt>@</tt> refers to the current node in the context of the evaluation of a filter expression (<xref target="filter-selector"/>).</t> </section> <section anchor="segments"> <name>Segments</name> <t>Segments select children (<tt>[<selectors>]</tt>) or descendants(<tt>..[<selectors>]</tt>)(<tt>..&wj;[<selectors>]</tt>) of an input value.</t> <t>Segments can use <em>bracket notation</em>, for example:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $['store']['book'][0]['title'] ]]></sourcecode> <t>or the more compact <em>dot notation</em>, for example:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $.store.book[0].title ]]></sourcecode> <t>Bracket notation containsa comma separated list ofone or more (comma-separated) selectors of any kind. Selectors are detailed in the next section.</t> <t>A JSONPath expression may use a combination of bracket and dot notations.</t> <t>This document treats the bracket notations as canonical and defines the shorthand dot notation in terms of bracket notation. Examples and descriptions useshorthandsshorthand where convenient.</t> </section> <section anchor="selectors"> <name>Selectors</name> <t>A name selector,e.g.e.g., <tt>'name'</tt>, selects a named child of an object.</t> <t>An index selector,e.g.e.g., <tt>3</tt>, selects an indexed child of an array.</t><t>A<t>In the expression <tt>[*]</tt>, a wildcard <tt>*</tt> (<xref target="wildcard-selector"/>)in the expression <tt>[*]</tt>selects all children of anodenode, and in the expression<tt>..[*]</tt><tt>..[*]</tt>, it selects all descendants of a node.</t> <t>An array slice <tt>start:end:step</tt> (<xref target="slice"/>) selects a series of 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 end.</t><t>Filter expressions<t>A filter expression <tt>?<logical-expr></tt>selectselects certain children of an object or array, as in:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $.store.book[?@.price < 10].title ]]></sourcecode> </section> <section anchor="summary"> <name>Summary</name> <t><xref target="tbl-overview"/> provides a brief overview of JSONPath syntax.</t> <table anchor="tbl-overview"> <name>Overview of JSONPathsyntax</name>Syntax</name> <thead> <tr> <th align="left">Syntax Element</th> <th align="left">Description</th> </tr> </thead> <tbody> <tr> <td align="left"> <tt>$</tt></td> <td align="left"> <xref target="root-identifier">root node identifier</xref></td> </tr> <tr> <td align="left"> <tt>@</tt></td> <td align="left"> <xref target="filter-selector">current node identifier</xref> (valid only within filter selectors)</td> </tr> <tr> <td align="left"> <tt>[<selectors>]</tt></td> <td align="left"> <xref target="child-segment">childsegment</xref>segment</xref>: selects zero or more children of anode; contains one or more selectors, separated by commas</td>node</td> </tr> <tr> <td align="left"> <tt>.name</tt></td> <td align="left">shorthand for <tt>['name']</tt></td> </tr> <tr> <td align="left"> <tt>.*</tt></td> <td align="left">shorthand for <tt>[*]</tt></td> </tr> <tr> <td align="left"><tt>..[<selectors>]</tt></td><tt>..&wj;[<selectors>]</tt></td> <td align="left"> <xref target="descendant-segment">descendant segment</xref>: selects zero or more descendants of anode; contains one or more selectors, separated by commas</td>node</td> </tr> <tr> <td align="left"> <tt>..name</tt></td> <td align="left">shorthand for <tt>..['name']</tt></td> </tr> <tr> <td align="left"> <tt>..*</tt></td> <td align="left">shorthand for <tt>..[*]</tt></td> </tr> <tr> <td align="left"> <tt>'name'</tt></td> <td align="left"> <xref target="name-selector">name selector</xref>: selects a named child of an object</td> </tr> <tr> <td align="left"> <tt>*</tt></td> <td align="left"> <xreftarget="name-selector">wildcardtarget="wildcard-selector">wildcard selector</xref>: selects all children of a node</td> </tr> <tr> <td align="left"> <tt>3</tt></td> <td align="left"> <xref target="index-selector">index selector</xref>: selects an indexed child of an array (from 0)</td> </tr> <tr> <td align="left"> <tt>0:100:5</tt></td> <td align="left"> <xref target="slice">array slice selector</xref>: start:end:step for arrays</td> </tr> <tr> <td align="left"> <tt>?<logical-expr></tt></td> <td align="left"> <xref target="filter-selector">filter selector</xref>: selects particular children using a logical expression</td> </tr> <tr> <td align="left"> <tt>length(@.foo)</tt></td> <td align="left"> <xref target="fnex">function extension</xref>: invokes a function in a filter expression</td> </tr> </tbody> </table> </section> </section> <section anchor="jsonpath-examples"> <name>JSONPath Examples</name> <t>This section is informative. It provides examples of JSONPath expressions.</t> <t>The examples are based on the simple JSON value shown in <xref target="fig-example-value"/>, representing a bookstore(that(which also has a bicycle).</t> <figure anchor="fig-example-value"> <name>Example JSONvalue</name>Value</name> <sourcecode type="json"><![CDATA[ { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 399 } } } ]]></sourcecode> </figure> <t><xref target="tbl-example"/> shows some JSONPath queries that might be applied to this example and their intended results.</t> <table anchor="tbl-example"> <name>Example JSONPathexpressionsExpressions andtheir intended results when appliedTheir Intended Results When Applied to theexampleExample JSONvalue</name>Value</name> <thead> <tr> <th align="left">JSONPath</th> <th align="left">Intendedresult</th>Result</th> </tr> </thead> <tbody> <tr> <td align="left"> <tt>$.store.book[*].author</tt></td> <td align="left">the authors of all books in the store</td> </tr> <tr> <td align="left"> <tt>$..author</tt></td> <td align="left">all authors</td> </tr> <tr> <td align="left"> <tt>$.store.*</tt></td> <td align="left">all things in the store, which are some books and a red bicycle</td> </tr> <tr> <td align="left"> <tt>$.store..price</tt></td> <td align="left">the prices of everything in the store</td> </tr> <tr> <td align="left"> <tt>$..book[2]</tt></td> <td align="left">the third book</td> </tr> <tr> <td align="left"> <tt>$..book[2].author</tt></td> <td align="left">the third book's author</td> </tr> <tr> <td align="left"> <tt>$..book[2].publisher</tt></td> <td align="left">empty result: the third book does not have a "publisher" member</td> </tr> <tr> <td align="left"> <tt>$..book[-1]</tt></td> <td align="left">the last book in order</td> </tr> <tr> <td align="left"> <tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> <td align="left">the first two books</td> </tr> <tr> <td align="left"> <tt>$..book[?@.isbn]</tt></td> <td align="left">all books with an ISBN number</td> </tr> <tr> <td align="left"> <tt>$..book[?@.price<10]</tt></td> <td align="left">all books cheaper than 10</td> </tr> <tr> <td align="left"> <tt>$..*</tt></td> <td align="left">all member values and array elements contained in the input value</td> </tr> </tbody> </table> </section> </section> <section anchor="jsonpath-syntax-and-semantics"> <name>JSONPath Syntax and Semantics</name> <section anchor="synsem-overview"> <name>Overview</name> <t>A JSONPath <em>expression</em> is a stringwhich,that, when applied to a JSONvalue, thevalue (the <em>queryargument</em>,argument</em>), selects zero or more nodes of the argument and outputs these nodes as a nodelist.</t> <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 first decoded into Unicode scalar values as described in <xref target="RFC3629"/>; implementation approaches that lead to an equivalent result are possible.</t> <t>A string to be used as a JSONPath query needs to be <em>well-formed</em> and <em>valid</em>. A string is a well-formed JSONPath query if it conforms to the ABNF syntax in this document. A well-formed JSONPath query is valid if it also fulfillsallboth semantic requirements posed by this document, whichare:</t>are as follows:</t> <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 within the range of exact integer values defined inI-JSONInternet JSON (I-JSON) (see <xref section="2.2" sectionFormat="of" target="RFC7493"/>), namely within the interval[−(2<sup>53</sup>)+1, (2<sup>53</sup>)−1].</li>[-(2<sup>53</sup>)+1, (2<sup>53</sup>)-1].</li> <li>Uses of function extensions <bcp14>MUST</bcp14> be <em>well-typed</em>, as described in <xreftarget="fnex"/>.</li>target="well-typedness"/>.</li> </ol> <t>A JSONPath implementation <bcp14>MUST</bcp14> raise an error for any querywhichthat is not well-formed and valid. 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 well-formedness and the validity of a JSONPath query can be raised during application of the query to a value. This clearly separates well-formedness/validity errors in the query from mismatches that may actually stem from flaws in the data.</t> <t>Mismatches between the structure expected by a valid query and the structure found in the data can lead to empty query results, which may be unexpected and indicate bugs in either. JSONPath implementations might therefore want to provide diagnostics to the application developer that aid in finding the cause of empty results.</t> <t>Obviously, an implementation can still fail when executing a JSONPath query, e.g., because of resource depletion, but this is not modeled in this document. However, the implementation <bcp14>MUST NOT</bcp14> silently malfunction. Specifically, if a valid JSONPath query is evaluated against a structured value whose size is too large to process the query correctly (forinstanceinstance, requiring the processing of numbers that fall outside the range of exact values), the implementation <bcp14>MUST</bcp14> provide an indication of overflow.</t> <t>(Readers familiar with the HTTP error model may be reminded of 400 type errors when pondering well-formedness and validity,whileand they may recognize resource depletion and related errorsareas comparable to 500 type errors.)</t> <section anchor="syntax"> <name>Syntax</name> <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, followed by a possibly empty sequence of <em>segments</em>.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ jsonpath-query = root-identifier segments segments = *(S segment) B = %x20 / ; Space %x09 / ; Horizontal tab %x0A / ; Line feed or New line %x0D ; Carriage return S = *B ; optional blank space ]]></sourcecode> <t>The syntax and semantics of segments are defined in <xref target="segments-details"/>.</t> </section> <section anchor="semantics"> <name>Semantics</name> <t>In this document, the semantics of a JSONPath query define the required results and do not prescribe the internal workings of an implementation. This document may describe semantics in a procedural step-by-stepfashion, butfashion; however, such descriptions are normative only in the sense that any implementation <bcp14>MUST</bcp14> produce an identicalresult,result but not in the sense thatimplementorsimplementers are required to use the same algorithms.</t> <t>The semantics are that a valid query is executed against avalue, thevalue (the <em>queryargument</em>,argument</em>) and produces a nodelist (i.e., a list of zero or more nodes of the value).</t> <t>The query is a root identifier followed by a sequence of zero or more segments, each of which is applied to the result of the previous root identifier or segment and provides input to the next segment. These results and inputs take the form of nodelists.</t> <t>The nodelist resulting from the root identifier contains a singlenode, thenode (the queryargument.argument). The nodelist resulting from the last segment is presented as the 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 Normalized Paths referencing the nodes, or both—-- or some other representation as desired by the implementation. Note:anAn empty nodelist is a valid query result.</t> <t>A segment operates on each of the nodes in its input nodelist in turn, and the resultant nodelists are concatenated in the order of the input nodelist they were derived from to produce 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> <t>A syntactically valid segment <bcp14>MUST NOT</bcp14> produce errors when executing the query. This means that some operations that might be considered erroneous, such as using an index lying outside the range of an array, simply result in fewer nodes being selected. (Additional discussion of this property can be found in the introductiontoof <xref target="synsem-overview"/>.)</t> <t>As a consequence of this approach, if any of the segments produces an empty nodelist, then the whole query produces an emptynodelist.</t>nodelist. </t> <t>If the semantics of a querymay producegive an implementation anodelist with more than onechoice of producing multiple possibleordering,orderings, a particular implementation mayalsoproduce distinct orderings in successive runs of the query.</t> </section> <section anchor="example"> <name>Example</name> <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 ofnodes: <tt>0</tt>, <tt>1</tt>nodes (denoted here by theirvalue).</t>values): <tt>0</tt>, <tt>1</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,<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 the node of any member value of the input node corresponding to the member name <tt>"a"</tt>. The result is again a listof onecontaining a single node: <tt>[{"b":0},{"b":1},{"c":2}]</tt>.</t> <t>Next, <tt>[*]</tt> selectsfrom any array input nodeallitsthe elements(for an object input node, it would select all its member values, but notfrom themember names).input array node. 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 member name <tt>b</tt> and selects the node of the member value of the input node corresponding to that name. The result is a list containing <tt>0</tt>, <tt>1</tt>. This is the concatenation of threelists,lists: two of length one containing <tt>0</tt>, <tt>1</tt>, respectively, and one of length zero.</t> </section> </section> <section anchor="root-identifier"> <name>Root Identifier</name> <section anchor="syntax-1"> <name>Syntax</name> <t>Every JSONPath query (except those inside filterexpressions,expressions; see <xref target="filter-selector"/>) <bcp14>MUST</bcp14> begin with the root identifier <tt>$</tt>.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ root-identifier = "$" ]]></sourcecode> </section> <section anchor="semantics-1"> <name>Semantics</name> <t>The root identifier <tt>$</tt> represents the root node of the query argument and produces a nodelist consisting of that root node.</t> </section> <section anchor="examples"> <name>Examples</name> <aside><t>In<t>Note: In this example and the following examples in Sections <xref format="counter" target="root-identifier"/> and <xref format="counter"target="selector-details"/>target="selector-details"/>, except for <xref target="tbl-comparison"/>, we will present a JSON text to show the JSON value used as the query argument to the queries in theexamples,examples and then a table with the following columns:</t> <ul spacing="normal"> <li>Query: an example query to be applied to the query argument</li> <li>Result: the query result as a list of JSON values that were located in the query argument</li> <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> <li>Comment: descriptive information</li> </ul> </aside> <t>JSON:</t> <sourcecode type="json"><![CDATA[ {"k": "v"} ]]></sourcecode> <t>Queries:</t> <table anchor="tbl-root"> <name>Rootidentifier examples</name>Identifier Example</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Path</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$</tt></td> <td align="left"> <tt>{"k": "v"}</tt></td> <td align="center"> <tt>$</tt></td> <td align="left">Root node</td> </tr> </tbody> </table> </section> </section> <section anchor="selector-details"> <name>Selectors</name> <t>Selectors appear only inside <xref target="child-segment">child segments</xref> and <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>There are various kinds of selectorswhichthat produce children of objects, children of arrays, or children of either objects or arrays.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ selector = name-selector / wildcard-selector / slice-selector / index-selector / filter-selector ]]></sourcecode> <t>The syntax and semantics of each kind of selector are defined below.</t> <section anchor="name-selector"> <name>Name Selector</name> <section anchor="syntax-name"> <name>Syntax</name> <t>A name selector <tt>'<name>'</tt> selects at most one object member value.</t> <t>In contrast to JSON, the JSONPath syntax allows strings to be enclosed in <em>single</em> or <em>double</em> quotes.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ name-selector = string-literal string-literal = %x22 *double-quoted %x22 / ; "string" %x27 *single-quoted %x27 ; 'string' double-quoted = unescaped / %x27 / ; ' ESC %x22 / ; \" ESC escapable single-quoted = unescaped / %x22 / ; " ESC %x27 / ; \' ESC escapable ESC = %x5C ; \ backslash unescaped = %x20-21 / ; see RFC 8259 ; omit 0x22 " %x23-26 / ; omit 0x27 ' %x28-5B / ; omit 0x5C \ %x5D-D7FF / ; skip surrogate code points %xE000-10FFFF escapable = %x62 / ; b BS backspace U+0008 %x66 / ; f FF form feed U+000C %x6E / ; n LF line feed U+000A %x72 / ; r CR carriage return U+000D %x74 / ; t HT horizontal tab U+0009 "/" / ; / slash (solidus) U+002F "\" / ; \ backslash (reverse solidus) U+005C (%x75 hexchar) ; uXXXX U+XXXX hexchar = non-surrogate / (high-surrogate "\" %x75 low-surrogate) non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / ("D" %x30-37 2HEXDIG ) high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" ]]></sourcecode> <t>Notes:</t> <ul spacing="normal"> <li><tt>double-quoted</tt><tt>Double-quoted</tt> strings follow the JSON string syntax (<xref section="7" sectionFormat="of" target="RFC8259"/>); <tt>single-quoted</tt> strings follow an analogouspattern (<xref target="syntax-index"/>).pattern. No attempt was made to improve on this syntax, so if it is desired to escape characters with scalar values above 0xFFFF, such as <uformat="num-lit-name">🤔</u>,format="num-lit-name">🎼</u>, they need to be represented by a pair of surrogate escapes(<tt>"\uD83E\uDD14"</tt>(<tt>"\uD83C\uDFBC"</tt> in this case).</li> <li>Alphabetic characters inABNFquoted strings arecase-insensitive,case-insensitive in ABNF, so each of the hexadecimal digits within <tt>\u</tt> escapes (as specified in rules referenced by <tt>hexchar</tt>) can be eitherlower caselowercase orupper case,uppercase, while the <tt>u</tt> in <tt>\u</tt> needs to belower caselowercase (indicated as <tt>%x75</tt>).</li> </ul> </section> <section anchor="semantics-2"> <name>Semantics</name> <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 replacing each escape sequence with its equivalent Unicode character, as shown in <xref target="tbl-esc"/>:</t> <table anchor="tbl-esc"> <name>Escape Sequence Replacements</name> <thead> <tr> <th align="center">Escape Sequence</th> <th align="center">Unicode Character</th> <th align="left">Description</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>\b</tt></td> <td align="center">U+0008</td> <td align="left">BS backspace</td> </tr> <tr> <td align="center"> <tt>\t</tt></td> <td align="center">U+0009</td> <td align="left">HT horizontal tab</td> </tr> <tr> <td align="center"> <tt>\n</tt></td> <td align="center">U+000A</td> <td align="left">LF line feed</td> </tr> <tr> <td align="center"> <tt>\f</tt></td> <td align="center">U+000C</td> <td align="left">FF form feed</td> </tr> <tr> <td align="center"> <tt>\r</tt></td> <td align="center">U+000D</td> <td align="left">CR carriage return</td> </tr> <tr> <td align="center"> <tt>\"</tt></td> <td align="center">U+0022</td> <td align="left">quotation mark</td> </tr> <tr> <td align="center"> <tt>\'</tt></td> <td align="center">U+0027</td> <td align="left">apostrophe</td> </tr> <tr> <td align="center"> <tt>\/</tt></td> <td align="center">U+002F</td> <td align="left">slash (solidus)</td> </tr> <tr> <td align="center"> <tt>\\</tt></td> <td align="center">U+005C</td> <td align="left">backslash (reverse solidus)</td> </tr> <tr> <td align="center"> <tt>\uXXXX</tt></td> <td align="center">see <xref target="syntax-name"/></td> <td align="left">hexadecimal escape</td> </tr> </tbody> </table> <t>Applying the <tt>name-selector</tt> to an object node selects a member value whose name equals the member name<tt>M</tt>,<tt>M</tt> or selects nothing if there is no such member value. Nothing is selected from a value that is not an object.</t> <t>Note:processingProcessing 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. Two strings <bcp14>MUST</bcp14> be considered equal if and only if they are identical 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> from the JSONPath ortothe member name strings in the JSON prior to comparison.</t> </section> <section anchor="examples-1"> <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> <sourcecode type="json"><![CDATA[ { "o":{"j j":{"j j": {"k.k": 3}}, "'": {"@": 2} } ]]></sourcecode> <t>Queries:</t> <t>The examples in <xref target="tbl-name"/> show the name selector in use by childsegments:</t>segments.</t> <table anchor="tbl-name"> <name>Nameselector examples</name>Selector Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"><tt>$.o['j j']</tt></td><tt>$.o['j j']</tt></td> <td align="left"> <tt>{"k.k": 3}</tt></td> <td align="center"><tt>$['o']['j j']</tt></td><tt>$['o']['j j']</tt></td> <td align="left">Namedvalue<br/>value in <br/>a nestedobject</td><br/>object</td> </tr> <tr> <td align="center"><tt>$.o['j j']['k.k']</tt></td><tt>$.o['j j']&wj;['k.k']</tt></td> <td align="left"> <tt>3</tt></td> <td align="center"><tt>$['o']['j j']['k.k']</tt></td><tt>$['o']['j j']&wj;['k.k']</tt></td> <td align="left">Nestingfurther down</td><br/>further <br/>down</td> </tr> <tr> <td align="center"><tt>$.o["j j"]["k.k"]</tt></td><tt>$.o["j j"]&wj;["k.k"]</tt></td> <td align="left"> <tt>3</tt></td> <td align="center"><tt>$['o']['j j']['k.k']</tt></td><tt>$['o']['j j']&wj;['k.k']</tt></td> <td align="left">Differentdelimiter in<br/>delimiter <br/>in the query,unchanged normalized path</td><br/>unchanged <br/>Normalized <br/>Path</td> </tr> <tr> <td align="center"> <tt>$["'"]["@"]</tt></td> <td align="left"> <tt>2</tt></td> <td align="center"> <tt>$['\'']['@']</tt></td> <td align="left">Unusualmember names</td><br/>member <br/>names</td> </tr> </tbody> </table> </section> </section> <section anchor="wildcard-selector"> <name>Wildcard Selector</name> <section anchor="syntax-2"> <name>Syntax</name> <t>The wildcard selector consists of an asterisk.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ wildcard-selector = "*" ]]></sourcecode> </section> <section anchor="semantics-3"> <name>Semantics</name> <t>A wildcard selector selects the nodes of all children of an object or array. The order in which the children of an object appear in the resultant nodelist is not stipulated, since JSON objects are unordered. 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, a number, a string, <tt>true</tt>, <tt>false</tt>, or <tt>null</tt>).</t> </section> <section anchor="examples-2"> <name>Examples</name> <t>JSON:</t> <sourcecode type="json"><![CDATA[ { "o": {"j": 1, "k": 2}, "a": [5, 3] } ]]></sourcecode> <t>Queries:</t> <t>The examples in <xref target="tbl-wild"/> show the wildcard selector in use by a childsegment:</t>segment.</t> <table anchor="tbl-wild"> <name>Wildcardselector examples</name>Selector Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$[*]</tt></td> <td align="left"> <tt>{"j": 1, "k": 2}</tt> <br/> <tt>[5, 3]</tt></td> <td align="center"> <tt>$['o']</tt> <br/> <tt>$['a']</tt></td> <td align="left">Object values</td> </tr> <tr> <td align="center"> <tt>$.o[*]</tt></td> <td align="left"> <tt>1</tt> <br/> <tt>2</tt></td> <td align="center"> <tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt></td> <td align="left">Object values</td> </tr> <tr> <td align="center"> <tt>$.o[*]</tt></td> <td align="left"> <tt>2</tt> <br/> <tt>1</tt></td> <td align="center"> <tt>$['o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> <td align="left">Alternative result</td> </tr> <tr> <td align="center"> <tt>$.o[*, *]</tt></td> <td align="left"> <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt></td> <td align="center"> <tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> <td align="left">Non-deterministic ordering</td> </tr> <tr> <td align="center"> <tt>$.a[*]</tt></td> <td align="left"> <tt>5</tt> <br/> <tt>3</tt></td> <td align="center"> <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt></td> <td align="left">Array members</td> </tr> </tbody> </table> <t>The example above with the query <tt>$.o[*, *]</tt> shows that the wildcard selector may produce nodelists in distinct orders each time it appears in the childsegment,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> </section> </section> <section anchor="index-selector"> <name>Index Selector</name> <section anchor="syntax-index"> <name>Syntax</name> <t>An index selector <tt><index></tt> matches at most one array element value.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ index-selector = int ; decimal integer int = "0" / (["-"] DIGIT1 *DIGIT) ; - optional DIGIT1 = %x31-39 ; 1-9 non-zero digit ]]></sourcecode> <t>Applying the numerical <tt>index-selector</tt> selects the corresponding 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 the I-JSON range of exactvalues, seevalues (see <xreftarget="synsem-overview"/>.</t>target="synsem-overview"/>).</t> <t>Notes:</t> <ul spacing="normal"> <li>An <tt>index-selector</tt> is an integer (in base 10, as in JSON numbers).</li> <li>As in JSON numbers, the syntax does not allow octal-like integers with leadingzeroszeros, such as <tt>01</tt> or <tt>-01</tt>.</li> </ul> </section> <section anchor="index-semantics"> <name>Semantics</name> <t>A non-negative <tt>index-selector</tt> applied to an array selects an array element using a zero-based index. For example, the selector <tt>0</tt> selects thefirstfirst, 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> <t>A negative <tt>index-selector</tt> counts from the array end backwards, obtaining an equivalent non-negative <tt>index-selector</tt> bysummingadding the length of the arraywithto the negative index. For example, the selector <tt>-1</tt> selects thelastlast, and the selector <tt>-2</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 not exist; this simply means that no element is selected.</t> </section> <section anchor="examples-3"> <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> <sourcecode type="json"><![CDATA[ ["a","b"] ]]></sourcecode> <t>Queries:</t> <t>The examples in <xref target="tbl-index"/> show the index selector in use by a child segment.</t> <table anchor="tbl-index"> <name>Indexselector examples</name>Selector Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$[1]</tt></td> <td align="left"> <tt>"b"</tt></td> <td align="center"> <tt>$[1]</tt></td> <td align="left">Element of array</td> </tr> <tr> <td align="center"> <tt>$[-2]</tt></td> <td align="left"> <tt>"a"</tt></td> <td align="center"> <tt>$[0]</tt></td> <td align="left">Element of array, from the end</td> </tr> </tbody> </table> </section> </section> <section anchor="slice"> <name>Array Sliceselector</name>Selector</name> <section anchor="syntax-3"> <name>Syntax</name> <t>The array slice selector has the form <tt><start>:<end>:<step></tt>. It matches elements from arrays starting at index<tt><start></tt>,<tt><start></tt> and ending at— but(but notincluding —including) <tt><end></tt>, while incrementing by <tt>step</tt> with a default of <tt>1</tt>.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ slice-selector = [start S] ":" S [end S] [":" [S step ]] start = int ; included in selection end = int ; not included in selection step = int ; default: 1 ]]></sourcecode> <t>The slice selector consists of three optional decimal integers separated by colons. The second colon can be omitted when the third integeris.</t>is omitted.</t> <t>To be valid, the integers provided <bcp14>MUST</bcp14> be in the I-JSON range of exactvalues, seevalues (see <xreftarget="synsem-overview"/>.</t>target="synsem-overview"/>).</t> </section> <section anchor="semantics-4"> <name>Semantics</name> <t>The slice selector was inspired by the slice operatorofthat was proposed for ECMAScript 4 (ES4), which wasdeprecated in 2014,never released, and that of Python.</t> <section anchor="informal-introduction"> <name>Informal Introduction</name> <t>This section is informative.</t> <t>Array slicing is inspired by the behavior of the <tt>Array.prototype.slice</tt> method of the JavaScriptlanguagelanguage, as defined by the ECMA-262 standard <xref target="ECMA-262"/>, with the addition of the <tt>step</tt> parameter, which is inspired by the Python slice expression.</t> <t>The array slice expression <tt>start:end:step</tt> selects elements at indices starting at <tt>start</tt>, incrementing by <tt>step</tt>, and ending with <tt>end</tt> (which is itself excluded). So, for example, the expression <tt>1:3</tt> (where <tt>step</tt> defaults to <tt>1</tt>) selects elements with indices <tt>1</tt> and <tt>2</tt> (in thatorder)order), whereas <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 reverse order. Thus, for example, <tt>5:1:-2</tt> selects elements with indices <tt>5</tt> and<tt>3</tt>, in<tt>3</tt> (in thatorderorder), and <tt>::-1</tt> selects all the elements of an array in reverse order.</t> <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 raises an error in this case.)</t> <t>The following section specifies the behavior fully, without depending on JavaScript or Python behavior.</t> </section> <section anchor="normative-semantics"> <name>Normative Semantics</name> <t>A slice expression selects a subset of the elements of the inputarray,array in the same order as the array or the reverse order, depending on the sign of the <tt>step</tt> parameter. 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 an iteration delta, <tt>step</tt>. Each of these parameters is optional. In the rest of this section, <tt>len</tt> denotes the length of the input array.</t> <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>, as shown in <xreftarget="tbl-slice-start-end"/>:</t>target="tbl-slice-start-end"/>.</t> <table anchor="tbl-slice-start-end"> <name>Defaultarray sliceArray Slice start and endvalues</name>Values</name> <thead> <tr> <th align="left">Condition</th> <th align="left">start</th> <th align="left">end</th> </tr> </thead> <tbody> <tr> <td align="left">step >= 0</td> <td align="left">0</td> <td align="left">len</td> </tr> <tr> <td align="left">step < 0</td> <td align="left">len - 1</td> <td align="left">-len - 1</td> </tr> </tbody> </table> <t>Slice expression parameters <tt>start</tt> and <tt>end</tt> are not directly usable as slice bounds and must first be normalized. Normalization for this purpose is defined as:</t> <sourcecode type="pseudocode"><![CDATA[ FUNCTION Normalize(i, len): IF i >= 0 THEN RETURN i ELSE RETURN len + i END IF ]]></sourcecode> <t>The result of the array index expression <tt>i</tt> applied to an array of length <tt>len</tt> is the result of the array slicing expression <tt>Normalize(i, len):Normalize(i, len)+1:1</tt>.</t> <t>Slice expression parameters <tt>start</tt> and <tt>end</tt> are used to derive slice bounds <tt>lower</tt> and <tt>upper</tt>. The direction of the iteration, defined by the sign of <tt>step</tt>, determines which of the parameters is the lower bound and which is the upper bound:</t> <sourcecode type="pseudocode"><![CDATA[ FUNCTION Bounds(start, end, step, len): n_start = Normalize(start, len) n_end = Normalize(end, len) IF step >= 0 THEN lower = MIN(MAX(n_start, 0), len) upper = MIN(MAX(n_end, 0), len) ELSE upper = MIN(MAX(n_start, -1), len-1) lower = MIN(MAX(n_end, -1), len-1) END IF RETURN (lower, upper) ]]></sourcecode> <t>The slice expression selects elements with indices between the lower and upper bounds. In the following pseudocode, <tt>a(i)</tt> is the <tt>i+1</tt>th element of the array <tt>a</tt> (i.e., <tt>a(0)</tt> is the first element, <tt>a(1)</tt> the second, and so forth).</t> <sourcecode type="pseudocode"><![CDATA[ IF step > 0 THEN i = lower WHILE i < upper: SELECT a(i) i = i + step END WHILE ELSE if step < 0 THEN i = upper WHILE lower < i: SELECT a(i) i = i + step END WHILE END IF ]]></sourcecode> <t>When <tt>step = 0</tt>, no elements areselectedselected, and the result array is empty.</t> </section> </section> <section anchor="examples-4"> <name>Examples</name> <t>JSON:</t> <sourcecode type="json"><![CDATA[ ["a", "b", "c", "d", "e", "f", "g"] ]]></sourcecode> <t>Queries:</t> <t>The examples in <xref target="tbl-slice"/> show the array slice selector in use by a childsegment:</t>segment.</t> <table anchor="tbl-slice"> <name>Arrayslice selector examples</name>Slice Selector Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$[1:3]</tt></td> <td align="left"> <tt>"b"</tt> <br/> <tt>"c"</tt></td> <td align="center"> <tt>$[1]</tt> <br/> <tt>$[2]</tt></td> <td align="left">Slice with default step</td> </tr> <tr> <td align="center"> <tt>$[5:]</tt></td> <td align="left"> <tt>"f"</tt> <br/> <tt>"g"</tt></td> <td align="center"> <tt>$[5]</tt> <br/> <tt>$[6]</tt></td> <td align="left">Slice with no end index</td> </tr> <tr> <td align="center"> <tt>$[1:5:2]</tt></td> <td align="left"> <tt>"b"</tt> <br/> <tt>"d"</tt></td> <td align="center"> <tt>$[1]</tt> <br/> <tt>$[3]</tt></td> <td align="left">Slice with step 2</td> </tr> <tr> <td align="center"> <tt>$[5:1:-2]</tt></td> <td align="left"> <tt>"f"</tt> <br/> <tt>"d"</tt></td> <td align="center"> <tt>$[5]</tt> <br/> <tt>$[3]</tt></td> <td align="left">Slice with negative step</td> </tr> <tr> <td align="center"> <tt>$[::-1]</tt></td> <td align="left"> <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"> <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> </tr> </tbody> </table> </section> </section> <section anchor="filter-selector"> <name>Filterselector</name>Selector</name> <t>Filter selectors are used to iterate over the elements or members of structured values, i.e., JSON arrays and objects. The structured values are identified in the nodelist offered by the child or descendant segment using the filter selector.</t> <t>For each iteration (element/member), a logicalexpression, theexpression (the <em>filterexpression</em>,expression</em>) isevaluatedevaluated, which decides whether the node of the element/member is selected. (While a logical expression evaluates to what mathematically is a Boolean value, this specification uses the term <em>logical</em> to maintain a distinction from the Boolean values that JSON can represent.)</t> <t>During the iteration process, the filter expression receives the node 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> <t>The current node can be used as the start of one or more JSONPath queries in subexpressions of the filter expression, notated via the current-node-identifier <tt>@</tt>. Each JSONPath query can be used either for testing existence of a 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 <em>function argument</em>.</t> <t>Filter selectors may use function extensions, which are covered in <xref target="fnex"/>. Within the logical expression for a filter selector, function expressions can be used to operate on nodelists and values. The set of available functions is extensible, with a number of functionspredefined, seepredefined (see <xreftarget="fnex"/>,target="fnex"/>) and the ability to register further functions provided by theFunction Extensions sub-registry"Function Extensions" subregistry (<xref target="iana-fnex"/>). When a function is defined, it is given a unique name, and its return value and each of its parametersisare given a <em>declared type</em>. The type system is limited in scope; its purpose is to express restrictions that, without functions, are implicit in the grammar of filter expressions. The type system also guides conversions (<xref target="type-conv"/>) that mimic the way different kinds of expressions are handled in the grammar when function expressions are not in use.</t> <section anchor="filter-selector-syntax"> <name>Syntax</name> <t>The filter selector has the form <tt>?<logical-expr></tt>.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ filter-selector = "?" S logical-expr ]]></sourcecode> <t>As the filter expression is composed ofside-effectconstituents freeconstituents,of side effects, the order of evaluation does not need to be (and is not) defined. Similarly, for conjunction (<tt>&&</tt>) and disjunction (<tt>||</tt>) (defined later), both a short-circuiting and a fully evaluating implementation will lead to the same result; both implementation strategies are therefore valid.</t> <t>The current node is accessible via the current node identifier <tt>@</tt>. This identifier addresses the current node of the filter-selector that is directly enclosing the identifier. Note:withinWithin nested filter-selectors, there is no syntax to address the current node of any other than the directly enclosing filter-selector (i.e., of filter-selectors enclosing the filter-selector that is directly enclosing the identifier).</t> <t>Logical expressions offer the usual Boolean operators (<tt>||</tt> for OR, <tt>&&</tt> for AND, and <tt>!</tt> for NOT). They have the normal semantics of Boolean algebra and obey its laws(see, for(for example, see <xref target="BOOLEAN-LAWS"/>). 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 a parenthesized expression (which was required in <xref target="JSONPath-orig"/>), although it can be, and the semantics are the same as without the parentheses.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ logical-expr = logical-or-expr logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) ; disjunction ; binds less tightly than conjunction logical-and-expr = basic-expr *(S "&&" S basic-expr) ; conjunction ; binds more tightly than disjunction basic-expr = paren-expr / comparison-expr / test-expr paren-expr = [logical-not-op S] "(" S logical-expr S ")" ; parenthesized expression logical-not-op = "!" ; logical NOT operator ]]></sourcecode> <t>A test expression either tests the existence of a node designated by an embedded query (see <xref target="extest"/>) or tests the result of a function expression (see <xref target="fnex"/>). In the latter case, if the function's declared result type is <tt>LogicalType</tt> (see <xref target="typesys"/>), it tests whether the result is <tt>LogicalTrue</tt>; if the function's declared result type is <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 test expression is not well-typed (see <xref target="well-typedness"/>).</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ test-expr = [logical-not-op S] (filter-query / ; existence/non-existence function-expr) ; LogicalType or NodesType filter-query = rel-query / jsonpath-query rel-query = current-node-identifier segments current-node-identifier = "@" ]]></sourcecode> <t>Comparison expressions are available for comparisons between primitive 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 which selects at most onenodenode, the value of which is then used; or function expressions (see <xref target="fnex"/>) of type <tt>ValueType</tt>.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ comparison-expr = comparable S comparison-op S comparable literal = number / string-literal / true / false / null comparable = literal / singular-query / ; singular query value function-expr ; ValueType comparison-op = "==" / "!=" / "<=" / ">=" / "<" / ">" singular-query = rel-singular-query / abs-singular-query rel-singular-query = current-node-identifier singular-query-segments abs-singular-query = root-identifier singular-query-segments singular-query-segments = *(S (name-segment / index-segment)) name-segment = ("[" name-selector "]") / ("." member-name-shorthand) index-segment = "[" index-selector "]" ]]></sourcecode> <t>Literals can be notated in the way that is usual for JSON (with the extension that strings can use single-quote delimiters).</t> <t>Note: Alphabetic characters inABNFquoted strings arecase-insensitive,case-insensitive in ABNF, so within a floating pointnumbernumber, the ABNF expression "e" can be either the character 'e' or 'E'.</t> <t><tt>true</tt>, <tt>false</tt>, and <tt>null</tt> arelower-caselowercase only (case-sensitive).</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ number = (int / "-0") [ frac ] [ exp ] ; decimal number frac = "." 1*DIGIT ; decimal fraction exp = "e" [ "-" / "+" ] 1*DIGIT ; decimal exponent true = %x74.72.75.65 ; true false = %x66.61.6c.73.65 ; false null = %x6e.75.6c.6c ; null ]]></sourcecode> <t><xref target="tbl-prec"/> lists filter expression operators in order of precedence from highest (binds most tightly) to lowest (binds least tightly).</t><!-- FIXME: Should the syntax column be split between unary and binary operators? --><table anchor="tbl-prec"> <name>Filterexpression operator precedence</name>Expression Operator Precedence</name> <thead> <tr> <th align="center">Precedence</th> <th align="center">Operator type</th> <th align="center">Syntax</th> </tr> </thead> <tbody> <tr> <td align="center">5</td> <td align="center">Grouping <br/> Function Expressions</td> <td align="center"> <tt>(...)</tt> <br/> <em>name</em><tt>(...)</tt></td> </tr> <tr> <td align="center">4</td> <td align="center">Logical NOT</td> <td align="center"> <tt>!</tt></td> </tr> <tr> <td align="center">3</td> <td align="center">Relations</td> <td align="center"><tt>==</tt> <tt>!=</tt><br/><tt><</tt> <tt><=</tt> <tt>></tt> <tt>>=</tt></td><tt>==</tt> <tt>!=</tt><br/><tt><</tt> <tt><=</tt> <tt>></tt> <tt>>=</tt></td> </tr> <tr> <td align="center">2</td> <td align="center">Logical AND</td> <td align="center"> <tt>&&</tt></td> </tr> <tr> <td align="center">1</td> <td align="center">Logical OR</td> <td align="center"> <tt>||</tt></td> </tr> </tbody> </table> </section> <section anchor="semantics-5"> <name>Semantics</name> <t>The filter selector works with arrays and objects exclusively. Its result is a list of<em>zero</em>,(<em>zero</em>, <em>one</em>,<em>multiple</em><em>multiple</em>, or<em>all</em> of<em>all</em>) their array elements or member values, respectively. Applied to a primitive value, it selects nothing (and therefore does not contribute to the result of the filter selector).</t> <t>In the resultant nodelist, children of an array are ordered by their position in the array. The order in which the children of an object (as opposed to an array) appear in the resultant nodelist is not stipulated, since JSON objects are unordered.</t> <section anchor="extest"> <name>Existence Tests</name> <t>A query by itself in a logical context is an existence testwhichthat yields true if the query selects at least one node and yields false if the query does not select any nodes.</t> <t>Existence tests differ from comparisons in that:</t> <ul spacing="normal"><li>they<li>They work with arbitrary relative or absolute queries (not just singular queries).</li><li>they<li>They work with queries that select structured values.</li> </ul> <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 the value <tt>null</tt>, use <tt>@.foo == null</tt> (see <xref target="null-semantics"/>) rather than the negated existence test <tt>!@.foo</tt> (which yields false if <tt>@.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 the value of that node is <tt>false</tt>.</t> </section> <section anchor="comparisons"> <name>Comparisons</name> <t>The comparison operators <tt>==</tt> and <tt><</tt> are definedfirstfirst, and then these are used to define <tt>!=</tt>, <tt><=</tt>, <tt>></tt>, and <tt>>=</tt>.</t> <t>When either side of a comparison results in an empty nodelist or the special result <tt>Nothing</tt> (see <xref target="typesys"/>):</t> <ul spacing="normal"><li>a<li>A comparison using the operator <tt>==</tt> yields true if and only the other side also results in an empty nodelist or the special result <tt>Nothing</tt>.</li><li>a<li>A comparison using the operator <tt><</tt> yields false.</li> </ul> <t>When any query or function expression on either side of a comparison results in a nodelist consisting of a single node, that side is replaced by the value of its node and then:</t> <ul spacing="normal"> <li><t>a<t>A comparison using the operator <tt>==</tt> yields true if and only if the comparison is between: </t> <ul spacing="normal"> <li>numbers expected tointeroperateinteroperate, as per <xref section="2.2" sectionFormat="of"target="RFC7493">I-JSON</xref>target="RFC7493">I-JSON</xref>, that compare equal using normal mathematical equality,</li><li>numbers<li>numbers, at least one of which is not expected to interoperate as per I-JSON, where the numbers compare equal using animplementation specificimplementation-specific equality,</li> <li>equal primitive valueswhichthat are not numbers,</li> <li>equal arrays, thatisis, arrays of the same length where each element of the first array is equal to the corresponding element of the second array, or</li> <li> <t>equal objects with no duplicate names, thatisis, where: </t> <ul spacing="normal"> <li>both objects have the same collection of names (with noduplicates),duplicates) and</li> <li>for each of those names, the values associated with the name by the objects are equal.</li> </ul> </li> </ul> </li> <li><t>a<t>A comparison using the operator <tt><</tt> yields true if and only if the comparison is between valueswhichthat are both numbers or both strings andwhichthat satisfy the comparison: </t> <ul spacing="normal"> <li>numbers expected tointeroperateinteroperate, as per <xref section="2.2" sectionFormat="of"target="RFC7493">I-JSON</xref>target="RFC7493">I-JSON</xref>, <bcp14>MUST</bcp14> compare using the normal mathematical ordering; numbers not expected tointeroperateinteroperate, as perI-JSONI-JSON, <bcp14>MAY</bcp14> compare using animplementation specific ordering</li>implementation-specific ordering,</li> <li>the empty string compares less than any non-emptystring</li>string, and</li> <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 the remainder of the first string compares less than the remainder of the second string.</li> </ul> </li> </ul> <t><tt>!=</tt>, <tt><=</tt>, <tt>></tt>, and <tt>>=</tt> are defined in terms of the other comparison operators. For any <tt>a</tt> and <tt>b</tt>:</t> <ul spacing="normal"> <li>The comparison <tt>a != b</tt> yields true if and only if <tt>a == b</tt> yields false.</li> <li>The comparison <tt>a <= b</tt> yields true if and only if <tt>a < b</tt> yields true or <tt>a == b</tt> yields true.</li> <li>The comparison <tt>a > b</tt> yields true if and only if <tt>b < a</tt> yields true.</li> <li>The comparison <tt>a >= b</tt> yields true if and only if <tt>b < a</tt> yields true or <tt>a == b</tt> yields true.</li> </ul> </section> </section> <section anchor="examples-5"> <name>Examples</name> <t>The first set of examples shows some comparison expressions and their result with a given JSON value as input.</t> <t>JSON:</t> <sourcecode type="json"><![CDATA[ { "obj": {"x": "y"}, "arr": [2, 3] } ]]></sourcecode> <t>Comparisons:</t> <table anchor="tbl-comparison"> <name>Comparisonexamples</name>Examples</name> <thead> <tr> <th align="center">Comparison</th> <th align="center">Result</th> <th align="center">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$.absent1 == $.absent2</tt></td> <td align="center">true</td> <td align="center">Empty nodelists</td> </tr> <tr> <td align="center"> <tt>$.absent1 <= $.absent2</tt></td> <td align="center">true</td> <td align="center"> <tt>==</tt> implies <tt><=</tt></td> </tr> <tr> <td align="center"> <tt>$.absent == 'g'</tt></td> <td align="center">false</td> <td align="center">Empty nodelist</td> </tr> <tr> <td align="center"> <tt>$.absent1 != $.absent2</tt></td> <td align="center">false</td> <td align="center">Empty nodelists</td> </tr> <tr> <td align="center"> <tt>$.absent != 'g'</tt></td> <td align="center">true</td> <td align="center">Empty nodelist</td> </tr> <tr> <td align="center"> <tt>1 <= 2</tt></td> <td align="center">true</td> <td align="center">Numeric comparison</td> </tr> <tr> <td align="center"> <tt>1 > 2</tt></td> <td align="center">false</td> <tdalign="center">Strict, numericalign="center">Numeric comparison</td> </tr> <tr> <td align="center"> <tt>13 == '13'</tt></td> <td align="center">false</td> <td align="center">Type mismatch</td> </tr> <tr> <td align="center"> <tt>'a' <= 'b'</tt></td> <td align="center">true</td> <td align="center">String comparison</td> </tr> <tr> <td align="center"> <tt>'a' > 'b'</tt></td> <td align="center">false</td> <tdalign="center">Strict, stringalign="center">String comparison</td> </tr> <tr> <td align="center"> <tt>$.obj == $.arr</tt></td> <td align="center">false</td> <td align="center">Type mismatch</td> </tr> <tr> <td align="center"> <tt>$.obj != $.arr</tt></td> <td align="center">true</td> <td align="center">Type mismatch</td> </tr> <tr> <td align="center"> <tt>$.obj == $.obj</tt></td> <td align="center">true</td> <td align="center">Object comparison</td> </tr> <tr> <td align="center"> <tt>$.obj != $.obj</tt></td> <td align="center">false</td> <td align="center">Object comparison</td> </tr> <tr> <td align="center"> <tt>$.arr == $.arr</tt></td> <td align="center">true</td> <td align="center">Array comparison</td> </tr> <tr> <td align="center"> <tt>$.arr != $.arr</tt></td> <td align="center">false</td> <td align="center">Array comparison</td> </tr> <tr> <td align="center"> <tt>$.obj == 17</tt></td> <td align="center">false</td> <td align="center">Type mismatch</td> </tr> <tr> <td align="center"> <tt>$.obj != 17</tt></td> <td align="center">true</td> <td align="center">Type mismatch</td> </tr> <tr> <td align="center"> <tt>$.obj <= $.arr</tt></td> <td align="center">false</td> <td align="center">Objects and arrays do not offer <tt><</tt> comparison</td> </tr> <tr> <td align="center"> <tt>$.obj < $.arr</tt></td> <td align="center">false</td> <td align="center">Objects and arrays do not offer <tt><</tt> comparison</td> </tr> <tr> <td align="center"> <tt>$.obj <= $.obj</tt></td> <td align="center">true</td> <td align="center"> <tt>==</tt> implies <tt><=</tt></td> </tr> <tr> <td align="center"> <tt>$.arr <= $.arr</tt></td> <td align="center">true</td> <td align="center"> <tt>==</tt> implies <tt><=</tt></td> </tr> <tr> <td align="center"> <tt>1 <= $.arr</tt></td> <td align="center">false</td> <td align="center">Arrays do not offer <tt><</tt> comparison</td> </tr> <tr> <td align="center"> <tt>1 >= $.arr</tt></td> <td align="center">false</td> <td align="center">Arrays do not offer <tt><</tt> comparison</td> </tr> <tr> <td align="center"> <tt>1 > $.arr</tt></td> <td align="center">false</td> <td align="center">Arrays do not offer <tt><</tt> comparison</td> </tr> <tr> <td align="center"> <tt>1 < $.arr</tt></td> <td align="center">false</td> <td align="center">Arrays do not offer <tt><</tt> comparison</td> </tr> <tr> <td align="center"> <tt>true <= true</tt></td> <td align="center">true</td> <td align="center"> <tt>==</tt> implies <tt><=</tt></td> </tr> <tr> <td align="center"> <tt>true > true</tt></td> <td align="center">false</td> <td align="center">Booleans do not offer <tt><</tt> comparison</td> </tr> </tbody> </table> <t>The second set of examples shows some complete JSONPath queries that make use of filterselectors,selectors and the results of evaluating these queries on a given JSON value as input. (Note:twoTwo of the queries employ function extensions; please see Sections <xref format="counter" target="match"/> and <xref format="counter" target="search"/>belowfor details about these.)</t> <t>JSON:</t> <sourcecode type="json"><![CDATA[ { "a": [3, 5, 1, 2, 4, 6, {"b": "j"}, {"b": "k"}, {"b": {}}, {"b": "kilo"} ], "o": {"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}}, "e": "f" } ]]></sourcecode> <t>Queries:</t> <t>The examples in <xref target="tbl-filter"/> show the filter selector in use by a childsegment:</t>segment.</t> <table anchor="tbl-filter"> <name>Filterselector examples</name>Selector Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$.a[?@.b == 'kilo']</tt></td> <td align="left"> <tt>{"b": "kilo"}</tt></td> <td align="center"> <tt>$['a'][9]</tt></td> <td align="left">Member value comparison</td> </tr> <tr> <td align="center"> <tt>$.a[?(@.b == 'kilo')]</tt></td> <td align="left"> <tt>{"b": "kilo"}</tt></td> <td align="center"> <tt>$['a'][9]</tt></td> <td align="left">Equivalent query with enclosing parentheses</td> </tr> <tr> <td align="center"> <tt>$.a[?@>3.5]</tt></td> <td align="left"> <tt>5</tt> <br/> <tt>4</tt> <br/> <tt>6</tt></td> <td align="center"> <tt>$['a'][1]</tt> <br/> <tt>$['a'][4]</tt> <br/> <tt>$['a'][5]</tt></td> <td align="left">Array value comparison</td> </tr> <tr> <td align="center"> <tt>$.a[?@.b]</tt></td> <td align="left"> <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b": {}}</tt> <br/> <tt>{"b": "kilo"}</tt></td> <td align="center"> <tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt> <br/> <tt>$['a'][8]</tt> <br/> <tt>$['a'][9]</tt></td> <td align="left">Array value existence</td> </tr> <tr> <td align="center"> <tt>$[?@.*]</tt></td> <td align="left"> <tt>[3, 5, 1, 2, 4, 6, {"b": "j"}, {"b": "k"}, {"b": {}}, {"b": "kilo"}]</tt> <br/> <tt>{"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}}</tt></td> <td align="center"> <tt>$['a']</tt> <br/> <tt>$['o']</tt></td> <td align="left">Existence of non-singular queries</td> </tr> <tr> <td align="center"> <tt>$[?@[?@.b]]</tt></td> <td align="left"> <tt>[3, 5, 1, 2, 4, 6, {"b": "j"}, {"b": "k"}, {"b": {}}, {"b": "kilo"}]</tt></td> <td align="center"> <tt>$['a']</tt></td> <td align="left">Nested filters</td> </tr> <tr> <td align="center"> <tt>$.o[?@<3, ?@<3]</tt></td> <td align="left"> <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt></td> <td align="center"> <tt>$['o']['p']</tt> <br/> <tt>$['o']['q']</tt> <br/> <tt>$['o']['q']</tt> <br/> <tt>$['o']['p']</tt></td> <td align="left">Non-deterministic ordering</td> </tr> <tr> <td align="center"> <tt>$.a[?@<2 || @.b == "k"]</tt></td> <td align="left"> <tt>1</tt> <br/> <tt>{"b": "k"}</tt></td> <td align="center"> <tt>$['a'][2]</tt> <br/> <tt>$['a'][7]</tt></td> <td align="left">Array value logical OR</td> </tr> <tr> <td align="center"> <tt>$.a[?match(@.b, "[jk]")]</tt></td> <td align="left"> <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt></td> <td align="center"> <tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt></td> <td align="left">Array value regular expression match</td> </tr> <tr> <td align="center"> <tt>$.a[?search(@.b, "[jk]")]</tt></td> <td align="left"> <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b": "kilo"}</tt></td> <td align="center"> <tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt> <br/> <tt>$['a'][9]</tt></td> <td align="left">Array value regular expression search</td> </tr> <tr> <td align="center"> <tt>$.o[?@>1 && @<4]</tt></td> <td align="left"> <tt>2</tt> <br/> <tt>3</tt></td> <td align="center"> <tt>$['o']['q']</tt> <br/> <tt>$['o']['r']</tt></td> <td align="left">Object value logical AND</td> </tr> <tr> <td align="center"> <tt>$.o[?@>1 && @<4]</tt></td> <td align="left"> <tt>3</tt> <br/> <tt>2</tt></td> <td align="center"> <tt>$['o']['r']</tt> <br/> <tt>$['o']['q']</tt></td> <td align="left">Alternative result</td> </tr> <tr> <td align="center"> <tt>$.o[?@.u || @.x]</tt></td> <td align="left"> <tt>{"u": 6}</tt></td> <td align="center"> <tt>$['o']['t']</tt></td> <td align="left">Object value logical OR</td> </tr> <tr> <td align="center"> <tt>$.a[?@.b == $.x]</tt></td> <td align="left"> <tt>3</tt> <br/> <tt>5</tt> <br/> <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>4</tt> <br/> <tt>6</tt></td> <td align="center"> <tt>$['a'][0]</tt> <br/><tt>$['a'][1]</tt> <br/> <tt>$['a'][2]</tt> <br/> <tt>$['a'][3]</tt> <br/> <tt>$['a'][4]</tt> <br/> <tt>$['a'][5]</tt></td> <td align="left">Comparison of queries with no values</td> </tr> <tr> <td align="center"> <tt>$.a[?@ == @]</tt></td> <td align="left"> <tt>3</tt> <br/> <tt>5</tt> <br/> <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>4</tt> <br/> <tt>6</tt> <br/> <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b": {}}</tt> <br/> <tt>{"b": "kilo"}</tt></td> <td align="center"> <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt> <br/><tt>$['a'][2]</tt> <br/><tt>$['a'][3]</tt> <br/><tt>$['a'][4]</tt> <br/><tt>$['a'][5]</tt> <br/><tt>$['a'][6]</tt> <br/><tt>$['a'][7]</tt> <br/><tt>$['a'][8]</tt> <br/><tt>$['a'][9]</tt></td> <td align="left">Comparisons of primitive and of structured values</td> </tr> </tbody> </table> <t>The example above with the query <tt>$.o[?@<3, ?@<3]</tt> shows that a filter selector may produce nodelists in distinct orders each time it appears in the child segment.</t> </section> </section> </section> <section anchor="fnex"> <name>Function Extensions</name> <t>Beyond the filter expression functionality defined in the preceding subsections, JSONPath defines an extension point that can be used to add filter expression functionality: "Function Extensions".</t> <t>This section defines the extension pointas well asand some function extensions that use this extension point. While these mechanisms are designed to use the extension point, they are an integral part of the JSONPath specification and are expected to be implemented like any other integral part of this specification.</t> <t>A function extension defines a registered name (see <xref target="iana-fnex"/>) that can be applied to a sequence of zero or more arguments, producing a result. Each registered function name is unique.</t> <t>A function extension <bcp14>MUST</bcp14> be defined such that its evaluation isside-effect free,free of side effects, i.e., all possible orders of evaluation and choices of short-circuiting or full evaluation of an expression containing it <bcp14>MUST</bcp14> lead to the same result. (Note:memoizationMemoization or logging are not side effects in this sense as they are visible at the implementation level only—-- they do not influence the result of the evaluation.)</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ function-name = function-name-first *function-name-char function-name-first = LCALPHA function-name-char = function-name-first / "_" / DIGIT LCALPHA = %x61-7A ; "a".."z" function-expr = function-name "(" S [function-argument *(S "," S function-argument)] S ")" function-argument = literal / filter-query / ; (includes singular-query) logical-expr / function-expr ]]></sourcecode> <t>Any function expressions in a query must be well-formed (by conforming to the above ABNF) andwell-typed, otherwisewell-typed; otherwise, the JSONPath implementation <bcp14>MUST</bcp14> raise an error (see <xref target="synsem-overview"/>). To define which function expressions are well-typed, a type system is first introduced.</t> <section anchor="typesys"> <name>Type System for Function Expressions</name> <t>Each parameteras well asand the result of a function extension must have a declared type.</t> <t>Declared types enable checking a JSONPath query for well-typedness 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> <table anchor="tbl-types"> <name>Functionextension type system</name>Extension Type System</name> <thead> <tr> <th align="left">Type</th> <th align="left">Instances</th> </tr> </thead> <tbody> <tr> <td align="left"> <tt>ValueType</tt></td> <td align="left">JSON values or <tt>Nothing</tt></td> </tr> <tr> <td align="left"> <tt>LogicalType</tt></td> <td align="left"> <tt>LogicalTrue</tt> or <tt>LogicalFalse</tt></td> </tr> <tr> <td align="left"> <tt>NodesType</tt></td> <td align="left">Nodelists</td> </tr> </tbody> </table> <t>Notes:</t> <ul spacing="normal"> <li>The only instances that can be directly represented in JSONPath syntax are certain JSON values in <tt>ValueType</tt> expressed as literals (which, in JSONPath, are limited to primitive values).</li> <li>The special result <tt>Nothing</tt> represents the absence of a JSON value and is distinct from any JSON value, including <tt>null</tt>.</li> <li> <tt>LogicalTrue</tt> and <tt>LogicalFalse</tt> are unrelated to the JSON values expressed by the literals <tt>true</tt> and <tt>false</tt>.</li> </ul> </section> <section anchor="type-conv"> <name>Type Conversion</name> <t>Just as queries can be used in logical expressions by testing for the existence of at least one node (<xref target="extest"/>), a function expression of declared type <tt>NodesType</tt> can be used as a function argument for a parameter of declared type <tt>LogicalType</tt>, with the equivalent conversion rule:</t> <ul spacing="normal"> <li>If the nodelist contains one or more nodes, the conversion result is <tt>LogicalTrue</tt>.</li> <li>If the nodelist is empty, the conversion result is <tt>LogicalFalse</tt>.</li> </ul> <t>Notes:</t> <ul spacing="normal"> <li>Extraction of a value from a nodelist can be performed in several ways, so an implicit conversion from <tt>NodesType</tt> to <tt>ValueType</tt> may be surprising and has therefore not been defined.</li> <li>A function expression with a declared type of <tt>NodesType</tt> can indirectly be used as an argument for a parameter of declared type <tt>ValueType</tt> by wrapping the expression in a call to a function extension, such as <tt>value()</tt> (see <xref target="value"/>), that takes a parameter of type <tt>NodesType</tt> and returns a result of type <tt>ValueType</tt>.</li> </ul> <t>The well-typedness of function expressions can now be defined in terms of this type system.</t> </section> <section anchor="well-typedness"> <name>Well-Typedness of Function Expressions</name> <t>For a function expression to be well-typed:</t> <ol spacing="normal"type="1"><li>itstype="1"> <li><t>Its declared type must be well-typed in the context in which itoccurs, and</li> <li>its arguments must be well-typed for the declared type of the corresponding parameters.</li> </ol> <t>(1) Asoccurs.</t> <t>As per the grammar, a function expression can occur in three different immediate contexts, which lead to the following conditions for well-typedness:</t> <dl newline="true"> <dt>As a <tt>test-expr</tt> in a logical expression:</dt> <dd> <t>The function's declared result type is<tt>LogicalType</tt>,<tt>LogicalType</tt> or (giving rise to conversion as per <xref target="type-conv"/>) <tt>NodesType</tt>.</t> </dd> <dt>As a <tt>comparable</tt> in a comparison:</dt> <dd> <t>The function's declared result type is <tt>ValueType</tt>.</t> </dd> <dt>As a <tt>function-argument</tt> in another function expression:</dt> <dd> <t>The function's declared result type fulfills the following rules for the corresponding parameter of the enclosing function.</t> </dd> </dl><t>(2) The</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 corresponding parameter, according to one of the following conditions:</t> <ul spacing="normal"> <li>When the argument is a function expression with the same declared result typethe sameas the declared type of the parameter.</li> <li> <t>When the declared type of the parameter is <tt>LogicalType</tt> and the argument is one of the following: </t> <ul spacing="normal"> <li>A function expression with declared result type <tt>NodesType</tt>. In thiscasecase, 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> </ul> </li> <li>When the declared type of the parameter is <tt>NodesType</tt> and the argument is a query (which includes singular query).</li> <li> <t>When the declared type of the parameter is <tt>ValueType</tt> and the argument is one of the following: </t> <ul spacing="normal"> <li>A value expressed as a literal.</li> <li> <t>A singular query. In this case: </t> <ul spacing="normal"> <li>If the query results in a nodelist consisting of a single node, the argument is the value of the node.</li> <li>If the query results in an empty nodelist, the argument is the special result <tt>Nothing</tt>.</li> </ul> </li> </ul> </li> </ul> </li> </ol> </section> <section anchor="length"> <name><tt>length()</tt> Function Extension</name> <dl> <dt>Parameters:</dt> <dd> <ol spacing="normal" type="1"><li> <tt>ValueType</tt></li> </ol> </dd> <dt>Result:</dt> <dd> <t><tt>ValueType</tt> (unsigned integer or <tt>Nothing</tt>)</t> </dd> </dl> <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 filter expression:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $[?length(@.authors) >= 5] ]]></sourcecode> <t>Its only argument is an instance of <tt>ValueType</tt> (possibly taken from a singular query, as in the example above). The resultalsois also an instance of <tt>ValueType</tt>: an unsigned integer or the special result <tt>Nothing</tt>.</t> <ul spacing="normal"> <li>If the argument value is a string, the result is the number of Unicode scalar values in the string.</li> <li>If the argument value is an array, the result is the number of elements in the array.</li> <li>If the argument value is an object, the result is the number of members in the object.</li> <li>For any other argument value, the result is the special result <tt>Nothing</tt>.</li> </ul> </section> <section anchor="count"> <name><tt>count()</tt> Function Extension</name> <dl> <dt>Parameters:</dt> <dd> <ol spacing="normal" type="1"><li> <tt>NodesType</tt></li> </ol> </dd> <dt>Result:</dt> <dd> <t><tt>ValueType</tt> (unsigned integer)</t> </dd> </dl> <t>The <tt>count()</tt> function extension provides a way to obtain the number of nodes in a nodelist and make that available for further processing in the filter expression:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $[?count(@.*.author) >= 5] ]]></sourcecode> <t>Its only argument is a nodelist. The result is avalue, anvalue (an unsignedinteger,integer) that gives the number of nodes in thenodelist. Notes:</t>nodelist.</t> <t>Notes:</t> <ul spacing="normal"> <li>There is no deduplication of the nodelist.</li> <li>The number of nodes in the nodelist is counted independent of their values or any children they mayhave;have, e.g., the count of a non-empty singular nodelist such as <tt>count(@)</tt> is always 1.</li> </ul> </section> <section anchor="match"> <name><tt>match()</tt> Function Extension</name> <dl> <dt>Parameters:</dt> <dd> <ol spacing="normal" type="1"><li> <tt>ValueType</tt> (string)</li> <li> <tt>ValueType</tt> (string conforming to <xreftarget="I-D.draft-ietf-jsonpath-iregexp"/>)</li>target="RFC9485"/>)</li> </ol> </dd> <dt>Result:</dt> <dd> <t><tt>LogicalType</tt></t> </dd> </dl> <t>The <tt>match()</tt> function extension provides a way to check whether (the entiretyof,of; see <xreftarget="search"/> below)target="search"/>) a given string matches a given regular expression, which is in the form described in <xreftarget="I-D.draft-ietf-jsonpath-iregexp"/> form.</t>target="RFC9485"/>.</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $[?match(@.date, "1974-05-..")] ]]></sourcecode> <t>Its arguments are instances of <tt>ValueType</tt> (possibly taken from a 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 string conforming to <xreftarget="I-D.draft-ietf-jsonpath-iregexp"/>,target="RFC9485"/>, the result is <tt>LogicalFalse</tt>. Otherwise, the string that is the first argument is matched against theiregexpI-Regexp contained in the string that is the second argument; the result is <tt>LogicalTrue</tt> if the string matches theiregexpI-Regexp and is <tt>LogicalFalse</tt> otherwise.</t> </section> <section anchor="search"> <name><tt>search()</tt> Function Extension</name> <dl> <dt>Parameters:</dt> <dd> <ol spacing="normal" type="1"><li> <tt>ValueType</tt> (string)</li> <li> <tt>ValueType</tt> (string conforming to <xreftarget="I-D.draft-ietf-jsonpath-iregexp"/>)</li>target="RFC9485"/>)</li> </ol> </dd> <dt>Result:</dt> <dd> <t><tt>LogicalType</tt></t> </dd> </dl> <t>The <tt>search()</tt> function extension provides a way to check whether a given string contains a substring that matches a given regular expression, which is in the form described in <xreftarget="I-D.draft-ietf-jsonpath-iregexp"/> form.</t>target="RFC9485"/>.</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $[?search(@.author, "[BR]ob")] ]]></sourcecode> <t>Its arguments are instances of <tt>ValueType</tt> (possibly taken from a 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 string conforming to <xreftarget="I-D.draft-ietf-jsonpath-iregexp"/>,target="RFC9485"/>, the result is <tt>LogicalFalse</tt>. Otherwise, the string that is the first argument is searched forat least onea substring that matches theiregexpI-Regexp contained in the string that is the second argument; the result is <tt>LogicalTrue</tt> if at least one suchasubstring exists and is <tt>LogicalFalse</tt> otherwise.</t> </section> <section anchor="value"> <name><tt>value()</tt> Function Extension</name> <dl> <dt>Parameters:</dt> <dd> <ol spacing="normal" type="1"><li> <tt>NodesType</tt></li> </ol> </dd> <dt>Result:</dt> <dd> <t><tt>ValueType</tt></t> </dd> </dl> <t>The <tt>value()</tt> function extension provides a way to convert an instance of <tt>NodesType</tt> to a value and make that available for further processing in the filter expression:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $[?value(@..color) == "red"] ]]></sourcecode> <t>Its only argument is an instance of <tt>NodesType</tt> (possibly taken from a <tt>filter-query</tt>, as in the example above). The result is an instance of <tt>ValueType</tt>.</t> <ul spacing="normal"> <li>If the argument contains a single node, the result is the value of the node.</li> <li>If the argument is thespecial result <tt>Nothing</tt>empty nodelist or contains multiple nodes, the result is <tt>Nothing</tt>.</li> </ul> <t>Note:aA singular query may be used anywhere where a ValueType is expected, so there is no need to use the <tt>value()</tt> function extension with a singular query.</t> </section> <section anchor="examples-6"> <name>Examples</name> <table anchor="tbl-function-expr"> <name>Functionexpression examples</name>Expression Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$[?length(@) < 3]</tt></td> <td align="left">well-typed</td> </tr> <tr> <td align="center"> <tt>$[?length(@.*) < 3]</tt></td> <td align="left">not well-typed since <tt>@.*</tt> is a non-singular query</td> </tr> <tr> <td align="center"> <tt>$[?count(@.*) == 1]</tt></td> <td align="left">well-typed</td> </tr> <tr> <td align="center"> <tt>$[?count(1) == 1]</tt></td> <td align="left">not well-typed since <tt>1</tt> is not a query or function expression</td> </tr> <tr> <td align="center"> <tt>$[?count(foo(@.*)) == 1]</tt></td> <td align="left">well-typed, where <tt>foo()</tt> is a function extension with a parameter of type <tt>NodesType</tt> and result type <tt>NodesType</tt></td> </tr> <tr> <td align="center"> <tt>$[?match(@.timezone, 'Europe/.*')]</tt></td> <td align="left">well-typed</td> </tr> <tr> <td align="center"> <tt>$[?match(@.timezone, 'Europe/.*') == true]</tt></td> <td align="left">not well-typed as <tt>LogicalType</tt> may not be used in comparisons</td> </tr> <tr> <td align="center"> <tt>$[?value(@..color) == "red"]</tt></td> <td align="left">well-typed</td> </tr> <tr> <td align="center"> <tt>$[?value(@..color)]</tt></td> <td align="left">not well-typed as <tt>ValueType</tt> may not be used in a test expression</td> </tr> <tr> <td align="center"> <tt>$[?bar(@.a)]</tt></td> <td align="left">well-typed for any function <tt>bar()</tt> with a parameter of any declared type and result type <tt>LogicalType</tt></td> </tr> <tr> <td align="center"> <tt>$[?bnl(@.*)]</tt></td> <td align="left">well-typed for any function <tt>bnl()</tt> with a parameter of declared type <tt>NodesType</tt> or <tt>LogicalType</tt> and result type <tt>LogicalType</tt></td> </tr> <tr> <td align="center"> <tt>$[?blt(1==1)]</tt></td> <td align="left">well-typed, where <tt>blt()</tt> is a function with a parameter of declared type <tt>LogicalType</tt> and result type <tt>LogicalType</tt></td> </tr> <tr> <td align="center"> <tt>$[?blt(1)]</tt></td> <td align="left">not well-typed for the same function <tt>blt()</tt>, as <tt>1</tt> is not a query, <tt>logical-expr</tt>, or function expression</td> </tr> <tr> <td align="center"> <tt>$[?bal(1)]</tt></td> <td align="left">well-typed, where <tt>bal()</tt> is a function with a parameter of declared type <tt>ValueType</tt> and result type <tt>LogicalType</tt></td> </tr> </tbody> </table> </section> </section> <section anchor="segments-details"> <name>Segments</name> <t>For each node in an input nodelist, segments apply one or more selectors to the node and concatenate the results of each selector into per-input-node nodelists, which are then concatenated in the order of the input nodelist to form a single 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 nodes of the resultant nodelist:</t> <ul spacing="normal"> <li>A query with N segments, where N >= 0, produces a nodelist consisting of nodes at depth in the input value of N or greater.</li> <li>A query with N segments, where N >= 0, all of which are <xref target="child-segment">child segments</xref>, produces a nodelist consisting of nodes precisely at depth N in the input value.</li> </ul> <t>There are two kinds ofsegment:segments: child segments and descendant segments.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ segment = child-segment / descendant-segment ]]></sourcecode> <t>The syntax and semantics of each kind of segment are defined below.</t> <section anchor="child-segment"> <name>Child Segment</name> <section anchor="syntax-4"> <name>Syntax</name> <t>The child segment consists of a non-empty, comma-separated sequence of selectors enclosed in square brackets.</t> <t>Shorthand notations are also provided for when there is a single wildcard or name selector.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ child-segment = bracketed-selection / ("." (wildcard-selector / member-name-shorthand)) bracketed-selection = "[" S selector *(S "," S selector) S "]" member-name-shorthand = name-first *name-char name-first = ALPHA / "_" / %x80-D7FF / ; skip surrogate code points %xE000-10FFFF name-char =DIGIT /name-first / DIGIT DIGIT = %x30-39 ; 0-9 ALPHA = %x41-5A / %x61-7A ; A-Z / a-z ]]></sourcecode> <t><tt>.*</tt>, a <tt>child-segment</tt> directly built from a <tt>wildcard-selector</tt>, is shorthand for <tt>[*]</tt>.</t> <t><tt>.<member-name></tt>, a <tt>child-segment</tt> built from a <tt>member-name-shorthand</tt>, is shorthand for <tt>['<member-name>']</tt>. Note:thisThis can only be used with member names that are composed of certain 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> </section> <section anchor="semantics-6"> <name>Semantics</name> <t>A child segment contains a sequence of selectors, each of which selects zero or more children of the input value.</t> <t>Selectors of different kinds may be combined within a single child segment.</t> <t>For each node in the input nodelist, the resulting nodelist of a child segment is the concatenation of the nodelists from each of its selectors in the order that the selectors appear in the list. Note:anyAny node matched by more than one selector is kept as many times in the nodelist.</t> <t>Where a selector can produce a nodelist in more than one possible order, each occurrence of the selector in the child segment mayevaluate toproduce a nodelist in a distinct order.</t><t>So<t>In summary, a child segment drills down one more level into the structure of the input value.</t> </section> <section anchor="examples-7"> <name>Examples</name> <t>JSON:</t> <sourcecode type="json"><![CDATA[ ["a", "b", "c", "d", "e", "f", "g"] ]]></sourcecode> <t>Queries:</t> <table anchor="tbl-child-segment"> <name>Childsegment examples</name>Segment Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$[0, 3]</tt></td> <td align="left"> <tt>"a"</tt> <br/> <tt>"d"</tt></td> <td align="center"> <tt>$[0]</tt> <br/> <tt>$[3]</tt></td> <td align="left">Indices</td> </tr> <tr> <td align="center"> <tt>$[0:2, 5]</tt></td> <td align="left"> <tt>"a"</tt> <br/> <tt>"b"</tt> <br/> <tt>"f"</tt></td> <td align="center"> <tt>$[0]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[5]</tt></td> <td align="left">Slice and index</td> </tr> <tr> <td align="center"> <tt>$[0, 0]</tt></td> <td align="left"> <tt>"a"</tt> <br/> <tt>"a"</tt></td> <td align="center"> <tt>$[0]</tt> <br/> <tt>$[0]</tt></td> <td align="left">Duplicated entries</td> </tr> </tbody> </table> </section> </section> <section anchor="descendant-segment"> <name>Descendant Segment</name> <section anchor="syntax-5"> <name>Syntax</name> <t>The descendant segment consists of a double dot <tt>..</tt> followed by a child segment (using bracket notation).</t><t>Shortand<t>Shorthand notations are also provided that correspond to the shorthand forms of the child segment.</t> <sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ descendant-segment = ".." (bracketed-selection / wildcard-selector / member-name-shorthand) ]]></sourcecode> <t><tt>..*</tt>, the <tt>descendant-segment</tt> directly built from a <tt>wildcard-selector</tt>, is shorthand for <tt>..[*]</tt>.</t> <t><tt>..<member-name></tt>, a <tt>descendant-segment</tt> built from a <tt>member-name-shorthand</tt>, is shorthand for<tt>..['<member-name>']</tt>.<tt>..&wj;['<member-name>']</tt>. Note:asAs with the similar shorthand of a <tt>child-segment</tt>, 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>.</t> <t>Note:<tt>..</tt> onOn itsownown, <tt>..</tt> is not a valid segment.</t> </section> <section anchor="semantics-7"> <name>Semantics</name> <t>A descendant segment produces zero or more descendants of an input value.</t> <t>For each node in the input nodelist, a descendant selector visits the input node and each of its descendants such that:</t> <ul spacing="normal"> <li>nodes of any array are visited in array order, and</li> <li>nodes are visited before their descendants.</li> </ul> <t>The order in which the children of an object are visited is not stipulated, since JSON objects are unordered.</t> <t>Suppose the descendant segment is of the form<tt>..[<selectors>]</tt><tt>..&wj;[<selectors>]</tt> (after converting any shorthand form to bracketnotation)notation), and the nodes, in the order visited, are <tt>D1</tt>, ..., <tt>Dn</tt> (where <tt>n >= 1</tt>). Note: <tt>D1</tt> is the input value.</t> <t>For each <tt>i</tt> such that <tt>1 <= i <= n</tt>, the nodelist <tt>Ri</tt> is defined to be a result of applying the child segment <tt>[<selectors>]</tt> to the node <tt>Di</tt>.</t> <t>For each node in the input nodelist, the result of the descendant segment is the concatenation of <tt>R1</tt>, ..., <tt>Rn</tt> (in that order). These results are then concatenated in input nodelist order to form the result of the segment.</t><t>So<t>In summary, a descendant segment drills down one or more levels into the structure of each input value.</t> </section> <section anchor="examples-8"> <name>Examples</name> <t>JSON:</t> <sourcecode type="json"><![CDATA[ { "o": {"j": 1, "k": 2}, "a": [5, 3, [{"j": 4}, {"k": 6}]] } ]]></sourcecode> <t>Queries:</t> <t>(Note that the fourth example can be expressed in two equivalent queries, shownherein <xref target="tbl-descendant-segment"/> in one table row instead of twoalmost identicalalmost-identical rows.)</t> <table anchor="tbl-descendant-segment"> <name>Descendantsegment examples</name>Segment Examples</name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$..j</tt></td> <td align="left"> <tt>1</tt> <br/> <tt>4</tt></td> <td align="center"> <tt>$['o']['j']</tt> <br/> <tt>$['a'][2][0]['j']</tt></td> <td align="left">Object values</td> </tr> <tr> <td align="center"> <tt>$..j</tt></td> <td align="left"> <tt>4</tt> <br/> <tt>1</tt></td> <td align="center"> <tt>$['a'][2][0]['j']</tt> <br/> <tt>$['o']['j']</tt></td> <td align="left">Alternative result</td> </tr> <tr> <td align="center"> <tt>$..[0]</tt></td> <td align="left"> <tt>5</tt> <br/> <tt>{"j": 4}</tt></td> <td align="center"> <tt>$['a'][0]</tt> <br/> <tt>$['a'][2][0]</tt></td> <td align="left">Array values</td> </tr> <tr> <td align="center"> <tt>$..[*]</tt> <br/>or<br/> <tt>$..*</tt></td> <td align="left"> <tt>{"j": 1, "k": 2}</tt> <br/> <tt>[5, 3, [{"j": 4}, {"k": 6}]]</tt> <br/> <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>5</tt> <br/> <tt>3</tt> <br/> <tt>[{"j": 4}, {"k": 6}]</tt> <br/> <tt>{"j": 4}</tt> <br/> <tt>{"k": 6}</tt> <br/> <tt>4</tt> <br/> <tt>6</tt></td> <td align="center"> <tt>$['o']</tt> <br/> <tt>$['a']</tt> <br/> <tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt> <br/> <tt>$['a'][2]</tt> <br/> <tt>$['a'][2][0]</tt> <br/> <tt>$['a'][2][1]</tt> <br/> <tt>$['a'][2][0]['j']</tt> <br/> <tt>$['a'][2][1]['k']</tt></td> <td align="left">All values</td> </tr> <tr> <td align="center"> <tt>$..o</tt></td> <td align="left"> <tt>{"j": 1, "k": 2}</tt></td> <td align="center"> <tt>$['o']</tt></td> <td align="left">Input value is visited</td> </tr> <tr> <td align="center"> <tt>$.o..[*, *]</tt></td> <td align="left"> <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt></td> <td align="center"> <tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> <td align="left">Non-deterministic ordering</td> </tr> <tr> <td align="center"> <tt>$.a..[0, 1]</tt></td> <td align="left"> <tt>5</tt> <br/> <tt>3</tt> <br/> <tt>{"j": 4}</tt> <br/> <tt>{"k": 6}</tt></td> <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> <td align="left">Multiple segments</td> </tr> </tbody> </table> <t>Note:theThe ordering of the results for the <tt>$..[*]</tt> and <tt>$..*</tt> examples above is not guaranteed, except that:</t> <ul spacing="normal"> <li> <tt>{"j": 1, "k": 2}</tt> must appear before <tt>1</tt> and <tt>2</tt>,</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> <li> <tt>5</tt> must appear before<tt>3</tt><tt>3</tt>, which must appear before <tt>[{"j": 4}, {"k": 6}]</tt>,</li> <li> <tt>5</tt> and <tt>3</tt> must appear before <tt>{"j": 4}</tt>, <tt>4</tt>,<tt>, {"k":<tt>{"k": 6}</tt>, and <tt>6</tt>,</li> <li> <tt>[{"j": 4}, {"k": 6}]</tt> must appear before <tt>{"j": 4}</tt> and <tt>{"k": 6}</tt>,</li> <li> <tt>{"j": 4}</tt> must appear before <tt>{"k": 6}</tt>,</li> <li> <tt>{"k": 6}</tt> must appear before <tt>4</tt>, and</li> <li> <tt>4</tt> must appear before <tt>6</tt>.</li> </ul> <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> <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 case for some JSONPath implementations that do not conform to this specification).</t> </section> </section> </section> <section anchor="null-semantics"> <name>Semantics of <tt>null</tt></name> <t>Note: JSON <tt>null</tt> is treated the same as any other JSONvalue:value, i.e., it is not taken to mean "undefined" or "missing".</t> <section anchor="examples-9"> <name>Examples</name> <t>JSON:</t> <sourcecode type="json"><![CDATA[ {"a": null, "b": [null], "c": [{}], "null": 1} ]]></sourcecode> <t>Queries:</t> <table anchor="tbl-null-examples"> <name>ExamplesinvolvingInvolving (ornot involving) null</name>Not Involving) <tt>null</tt></name> <thead> <tr> <th align="center">Query</th> <th align="left">Result</th> <th align="center">Result Paths</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$.a</tt></td> <td align="left"> <tt>null</tt></td> <td align="center"> <tt>$['a']</tt></td> <td align="left">Object value</td> </tr> <tr> <td align="center"> <tt>$.a[0]</tt></td> <tdalign="left"> </td>align="left"> </td> <tdalign="center"> </td>align="center"> </td> <td align="left"> <tt>null</tt> used as array</td> </tr> <tr> <td align="center"> <tt>$.a.d</tt></td> <tdalign="left"> </td>align="left"> </td> <tdalign="center"> </td>align="center"> </td> <td align="left"> <tt>null</tt> used as object</td> </tr> <tr> <td align="center"> <tt>$.b[0]</tt></td> <td align="left"> <tt>null</tt></td> <td align="center"> <tt>$['b'][0]</tt></td> <td align="left">Array value</td> </tr> <tr> <td align="center"> <tt>$.b[*]</tt></td> <td align="left"> <tt>null</tt></td> <td align="center"> <tt>$['b'][0]</tt></td> <td align="left">Array value</td> </tr> <tr> <td align="center"> <tt>$.b[?@]</tt></td> <td align="left"> <tt>null</tt></td> <td align="center"> <tt>$['b'][0]</tt></td> <td align="left">Existence</td> </tr> <tr> <td align="center"> <tt>$.b[?@==null]</tt></td> <td align="left"> <tt>null</tt></td> <td align="center"> <tt>$['b'][0]</tt></td> <td align="left">Comparison</td> </tr> <tr> <td align="center"> <tt>$.c[?@.d==null]</tt></td> <tdalign="left"> </td>align="left"> </td> <tdalign="center"> </td>align="center"> </td> <td align="left">Comparison with "missing" value</td> </tr> <tr> <td align="center"> <tt>$.null</tt></td> <td align="left"> <tt>1</tt></td> <td align="center"> <tt>$['null']</tt></td> <td align="left">Not JSONnull<tt>null</tt> at all, just a member name string</td> </tr> </tbody> </table> </section> </section> <section anchor="normalized-paths"> <name>Normalized Paths</name> <t>A Normalized Path is a unique representation of the location of a node in a valuewhichthat uniquely identifies the node in the value. Specifically, a Normalized Path is a JSONPath query with restricted syntax (defined below), e.g., <tt>$['book'][3]</tt>, which when applied to thevaluevalue, results in a nodelist consisting of just the node identified by the Normalized Path. Note:aA Normalized Path represents the identity of a node <em>in a specific value</em>. There is precisely one Normalized Path identifying any particular node in a value.</t> <t>A nodelist may be represented compactly in JSON as an array of strings, where the strings are Normalized Paths.</t> <t>Normalized Paths provide a predictable format that simplifies testing and post-processing of nodelists, e.g., to remove duplicate nodes. 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>Single quotes are used in Normalized Paths to delimit string member names. This reduces the number of characters that need escaping when Normalized Paths appear in strings delimited by doublequote-delimited strings,quotes, e.g., in JSON texts.</t> <t>Certain characters are escaped in NormalizedPaths,Paths in one and only one way; all other characters are unescaped.</t> <aside> <t>Note: Normalized Paths are singular queries, but not all singular queries are Normalized Paths. For example, <tt>$[-3]</tt> is a singularquery,query but is not a Normalized Path. The Normalized Path equivalent to <tt>$[-3]</tt> would have an index equal to the array length minus <tt>3</tt>. (The array length must be at least <tt>3</tt> if <tt>$[-3]</tt> is to identify a node.)</t> </aside> <sourcecode type="abnf" name="normalized-path-collected.abnf"><![CDATA[ normalized-path = root-identifier *(normal-index-segment) normal-index-segment = "[" normal-selector "]" normal-selector = normal-name-selector / normal-index-selector normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' normal-single-quoted = normal-unescaped / ESC normal-escapable normal-unescaped = ; omit %x0-1F control codes %x20-26 / ; omit 0x27 ' %x28-5B / ; omit 0x5C \ %x5D-D7FF / ; skip surrogate code points %xE000-10FFFF normal-escapable = %x62 / ; b BS backspace U+0008 %x66 / ; f FF form feed U+000C %x6E / ; n LF line feed U+000A %x72 / ; r CR carriage return U+000D %x74 / ; t HT horizontal tab U+0009 "'" / ; ' apostrophe U+0027 "\" / ; \ backslash (reverse solidus) U+005C (%x75 normal-hexchar) ; certain values u00xx U+00XX normal-hexchar = "0" "0" ( ("0" %x30-37) / ; "00"-"07" ; omit U+0008-U+000A BS HT LF ("0" %x62) / ; "0b" ; omit U+000C-U+000D FF CR ("0" %x65-66) / ; "0e"-"0f" ("1" normal-HEXDIG) ) normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" normal-index-selector = "0" / (DIGIT1 *DIGIT) ; non-negative decimal integer ]]></sourcecode> <t>Since there can only be one Normalized Path identifying a given node, the syntax stipulates which characters are escaped and which are not. So the definition of <tt>normal-hexchar</tt> is designed for hex escaping of characterswhichthat are not straightforwardly printable, forexampleexample, U+000B LINE TABULATION, but for which no standard JSON escape, such as <tt>\n</tt>, is available.</t> <section anchor="examples-10"> <name>Examples</name> <table anchor="tbl-normalized-path-examples"> <name>Normalized Pathexamples</name>Examples</name> <thead> <tr> <th align="center">Path</th> <th align="center">Normalized Path</th> <th align="left">Comment</th> </tr> </thead> <tbody> <tr> <td align="center"> <tt>$.a</tt></td> <td align="center"> <tt>$['a']</tt></td> <td align="left">Object value</td> </tr> <tr> <td align="center"> <tt>$[1]</tt></td> <td align="center"> <tt>$[1]</tt></td> <td align="left">Array index</td> </tr> <tr> <td align="center"> <tt>$[-3]</tt></td> <td align="center"> <tt>$[2]</tt></td> <td align="left">Negative array index for an array of length 5</td> </tr> <tr> <td align="center"> <tt>$.a.b[1:2]</tt></td> <td align="center"> <tt>$['a']['b'][1]</tt></td> <td align="left">Nested structure</td> </tr> <tr> <td align="center"> <tt>$["\u000B"]</tt></td> <td align="center"> <tt>$['\u000b']</tt></td> <td align="left">Unicode escape</td> </tr> <tr> <td align="center"> <tt>$["\u0061"]</tt></td> <td align="center"> <tt>$['a']</tt></td> <td align="left">Unicode character</td> </tr> </tbody> </table> </section> </section> </section> <section anchor="IANA"> <name>IANA Considerations</name><t><cref anchor="replace-xxxx">RFC Ed.: throughout this section, please replace RFCXXXX with the RFC number of this specification and remove this note.</cref></t><section anchor="registration-of-media-type-applicationjsonpath"> <name>Registration of Media Type application/jsonpath</name> <t>IANAis requested to registerhas registered the following media type <xref target="RFC6838"/>:</t> <dl> <dt>Type name:</dt> <dd> <t>application</t> </dd> <dt>Subtype name:</dt> <dd> <t>jsonpath</t> </dd> <dt>Required parameters:</dt> <dd> <t>N/A</t> </dd> <dt>Optional parameters:</dt> <dd> <t>N/A</t> </dd> <dt>Encoding considerations:</dt> <dd> <t>binary (UTF-8)</t> </dd> <dt>Security considerations:</dt> <dd> <t>See the Security Considerations section ofRFCXXXX.</t>RFC 9535.</t> </dd> <dt>Interoperability considerations:</dt> <dd> <t>N/A</t> </dd> <dt>Published specification:</dt> <dd><t>RFCXXXX</t><t>RFC 9535</t> </dd> <dt>Applications that use this media type:</dt> <dd> <t>Applications that need to convey queries in JSON data</t> </dd> <dt>Fragment identifier considerations:</dt> <dd> <t>N/A</t> </dd> <dt>Additional information:</dt><dd> <dl><dd><t><br/></t> <dl spacing="compact"> <dt>Deprecated alias names for this type:</dt> <dd> <t>N/A</t> </dd> <dt>Magic number(s):</dt> <dd> <t>N/A</t> </dd> <dt>File extension(s):</dt> <dd> <t>N/A</t> </dd> <dt>Macintosh file type code(s):</dt> <dd> <t>N/A</t> </dd> </dl> </dd></dl> <t>Person<dt>Person & email address to contact for furtherinformation: iesg@ietf.org</t> <dl>information:</dt> <dd>iesg@ietf.org</dd> <dt>Intended usage:</dt> <dd> <t>COMMON</t> </dd> <dt>Restrictions on usage:</dt> <dd> <t>N/A</t> </dd> <dt>Author:</dt> <dd> <t>JSONPath WG</t> </dd> <dt>Change controller:</dt> <dd> <t>IETF</t> </dd><dt>Provisional registration? (standards tree only):</dt> <dd> <t>no</t> </dd></dl> </section> <section anchor="iana-fnex"> <name>FunctionExtensions</name> <t>This specification definesExtensions Subregistry</name> <t>Per this specification, IANA has created a new "FunctionExtensions sub-registry"Extensions" subregistry in a new"JSONPath Parameters registry", with"JSONPath" registry. The "Function Extensions" subregistry has the policy"expert review""Expert Review" (<xref section="4.5" sectionFormat="of"target="BCP26"/>).</t>target="RFC8126"></xref>).</t> <t anchor="de-instructions">The experts are instructed to be frugal in the allocation of function extension names that are suggestive of generally applicable semantics, keeping them in reserve for functions that are likely to enjoy wide use and can make good use of their conciseness. The expert is also instructed to direct the registrant to provide a specification (<xref section="4.6" sectionFormat="of"target="BCP26"/>),target="RFC8126"></xref>) but can make exceptions, forinstanceinstance, when a specification is not available at the time of registration but is likely forthcoming. If the expert becomes aware of function extensions that are deployed and in use, they may also initiate a registration on their own if they deem such a registration can avert potential future collisions.</t> <t>Each entry in thesub-registrysubregistry mustinclude:</t>include the following:</t> <dl newline="true"> <dt>Function Name:</dt> <dd><t>a lower case<t>A lowercase ASCII <xreftarget="STD80"/>target="RFC0020"/> string that starts with a letter and can contain letters,digitsdigits, and underscore characters afterwards (<tt>[a-z][_a-z0-9]*</tt>). No other entry in thesub-registrysubregistry can have the same function name.</t> </dd> <dt>Brief description:</dt> <dd><t>a<t>A brief description</t> </dd> <dt>Parameters:</dt> <dd> <t>A comma-separated list of zero or more declared types, one for each of the arguments expected for this function extension</t> </dd> <dt>Result:</dt> <dd> <t>The declared type of the result for this function extension</t> </dd> <dt>Change Controller:</dt> <dd><t>(see<t>See <xref section="2.3" sectionFormat="of"target="BCP26"/>)</t>target="RFC8126"></xref>.</t> </dd> <dt>Reference:</dt> <dd><t>a<t>A reference document that provides a description of the function extension</t> </dd> </dl><t>Initial<t>The initial entries in thissub-registrysubregistry areaslisted in <xref target="pre-reg"/>; the entries in theColumn"Change Controller" column all have the value"IETF""IETF", and the entries in thecolumn"Reference" column all have the value "<xref target="fnex"/> ofRFCXXXX":</t>RFC 9535":</t> <table anchor="pre-reg"> <name>Initial Entries in the Function Extensions Subregistry</name> <thead> <tr> <th align="left">Function Name</th> <th align="left">Briefdescription</th>Description</th> <th align="left">Parameters</th> <th align="left">Result</th> </tr> </thead> <tbody> <tr> <td align="left">length</td> <td align="left">length of string, array, or object</td> <td align="left"> <tt>ValueType</tt></td> <td align="left"> <tt>ValueType</tt></td> </tr> <tr> <td align="left">count</td> <td align="left">size of nodelist</td> <td align="left"> <tt>NodesType</tt></td> <td align="left"> <tt>ValueType</tt></td> </tr> <tr> <td align="left">match</td> <td align="left">regular expression full match</td> <td align="left"> <tt>ValueType</tt>, <tt>ValueType</tt></td> <td align="left"> <tt>LogicalType</tt></td> </tr> <tr> <td align="left">search</td> <td align="left">regular expression substring match</td> <td align="left"> <tt>ValueType</tt>, <tt>ValueType</tt></td> <td align="left"> <tt>LogicalType</tt></td> </tr> <tr> <td align="left">value</td> <td align="left">value of the single node in nodelist</td> <td align="left"> <tt>NodesType</tt></td> <td align="left"> <tt>ValueType</tt></td> </tr> </tbody> </table> </section> </section> <section anchor="Security"> <name>Security Considerations</name> <t>Security considerations for JSONPath can stemfrom</t>from:</t> <ul spacing="normal"> <li>attack vectors on JSONPath implementations,</li> <li>attack vectors on how JSONPath queries are formed, and</li> <li>the way JSONPath is used in security-relevant mechanisms.</li> </ul> <section anchor="attack-vectors-on-jsonpath-implementations"> <name>Attack Vectors on JSONPath Implementations</name> <t>Historically, JSONPath has often been implemented by feeding parts of the query to an underlying programming language engine, e.g., JavaScript's <tt>eval()</tt> function. This approach is well known to lead to injection attacks and would require perfect input validation to prevent these attacks (see <xref section="12" sectionFormat="of" target="RFC8259"/> for similar considerations for JSON itself). Instead, JSONPath implementations need to implement the entire syntax of the query without relying on the parsers of programming language engines.</t> <t>Attacks on availability may attempt to trigger unusually expensive runtime performance exhibited by certain implementations in certain cases. (See <xref section="10" sectionFormat="of" target="RFC8949"/> for issues in hash-tableimplementations,implementations and <xref section="8" sectionFormat="of"target="I-D.draft-ietf-jsonpath-iregexp"/>target="RFC9485"/> for performance issues in regular expression implementations.) Implementers need to be aware that good average performance is not sufficient as long as an attacker can choose to submit specially crafted JSONPath queries or query arguments that trigger surprisingly high, possibly exponential, CPU usage or, forexampleexample, via a naive recursive implementation of the descendant segment, stack overflow. Implementations need to have appropriate resource management to mitigate these attacks.</t> </section> <section anchor="attack-vectors-on-how-jsonpath-queries-are-formed"> <name>Attack Vectors on How JSONPath QueriesareAre Formed</name> <t>JSONPath queries are often notstatic,static but formed from variables that provide index values, member names, or values to compare with in a filter expression. 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 (e.g., by escaping string delimiters). Not performing these validations and translations correctly can lead to unexpected failures, which can lead toAvailability, Confidentiality,availability, confidentiality, andIntegrityintegrity breaches, inparticularparticular, if an adversary has control over the values (e.g., by entering them into aWebweb form). The resulting class of attacks, <em>injections</em> (e.g., SQL injections), is consistently found among the top causes of application security vulnerabilities and requires particular attention.</t> </section> <section anchor="attacks-on-security-mechanisms-that-employ-jsonpath"> <name>Attacks on Security MechanismsthatThat Employ JSONPath</name> <t>Where JSONPath is used as a part of a security mechanism, attackers can attempt to provoke unexpected or unpredictablebehavior,behavior or take advantage of differences in behavior between JSONPath implementations.</t> <t>Unexpected or unpredictable behavior can arise from a query argument with certain constructs described as unpredictable by <xref target="RFC8259"/>. Predictable behavior can be expected, except in relation to the ordering of objects, for any query argument conforming with <xref target="RFC7493"/>.</t> <t>Other attacks can target the behavior of underlyingtechnologiestechnologies, such as UTF-8 (see <xref section="10" sectionFormat="of" target="RFC3629"/>) and the Unicode character set.</t> </section> </section> </middle> <back> <references> <name>References</name> <references anchor="sec-normative-references"> <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 constants to identify various protocol parameters. To ensure that the values in these fields do not have conflicting uses and to promote interoperability, their allocations 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 describing the conditions under which new values should be assigned, as well as when 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 Considerations 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 5226.</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 Universal Character Set (UCS) which encompasses most of the world's writing systems. The originally proposed encodings of the UCS, however, were not compatible with many current applications and protocols, and this has led to the development of UTF-8, the object of this memo. UTF-8 has the characteristic of preserving the full 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="Crocker"/> <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 Augmented BNF (ABNF), has been popular among many Internet specifications. The current specification documents ABNF. It balances compactness and simplicity with reasonable representational power. The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ranges. This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specifications. [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 ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t> <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability 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 JSON 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 registration of media types for use in HTTP, MIME, and other Internet protocols. This 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 expressions that is limited in scope with the goal of interoperation across many different regular-expression libraries. </t> </abstract> </front> <seriesInfo name="Internet-Draft" value="draft-ietf-jsonpath-iregexp-08"/> </reference><xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0020.xml"/> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml"/> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3629.xml"/> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"/> <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/Unicode14.0.0/UnicodeStandard-14.0.pdf">target="https://www.unicode.org/versions/latest/"> <front> <title>The Unicode®Standard: Version 14.0 - Core Specification</title>Standard</title> <author> <organization>The Unicode Consortium</organization> </author><date year="2021" month="September"/></front></reference> <reference anchor="RFC2119"> <front> <title>Key words for use in RFCs to Indicate Requirement Levels</title> <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 signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, 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</title> <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 protocol specifications. This document aims to reduce<annotation>At theambiguity by clarifying that only UPPERCASE usagetime ofthe 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"/>writing, <eref target="https://www.unicode.org/versions/Unicode15.0.0/UnicodeStandard-15.0.pdf" brackets="angle"/>.</annotation> </reference> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/> <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/> </references> <references anchor="sec-informative-references"> <name>Informative References</name> <reference anchor="COMPARISON" target="https://cburgmer.github.io/json-path-comparison/"> <front> <title>JSONPath Comparison</title> <author initials="C." surname="Burgmer" fullname="Christoph Burgmer"> <organization>Thoughtworks</organization> </author><date>n.d.</date></front> </reference><reference anchor="RFC6901"> <front> <title>JavaScript Object Notation (JSON) Pointer</title> <author fullname="P. Bryan" initials="P." role="editor" surname="Bryan"/> <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><xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6901.xml"/> <reference anchor="JSONPath-orig" target="https://goessner.net/articles/JsonPath/"> <front> <title>JSONPath—- XPath for JSON</title> <author initials="S." surname="Gössner" fullname="Stefan Gössner"> <organization>Fachhochschule Dortmund</organization> </author> <date year="2007"month="February" day="21"/>month="February"/> </front> </reference> <reference anchor="XPath" target="https://www.w3.org/TR/2010/REC-xpath20-20101214/"> <front> <title>XML Path Language (XPath) 2.0 (Second Edition)</title> <author fullname="Anders Berglund" role="editor"/> <author fullname="Don Chamberlin" role="editor"/> <author fullname="Jerome Simeon" role="editor"/> <author fullname="Jonathan Robie" role="editor"/> <author fullname="Mary Fernandez" role="editor"/> <author fullname="Michael Kay" role="editor"/> <author fullname="Scott Boag" role="editor"/> <date day="14" month="December" year="2010"/> </front> <seriesInfoname="W3C REC" value="REC-xpath20-20101214"/> <seriesInfoname="W3C" value="REC-xpath20-20101214"/> </reference> <referenceanchor="E4X">anchor="E4X" target="https://www.iso.org/standard/41002.html"> <front> <title>Information technology—- ECMAScript for XML (E4X) specification</title> <author> <organization>ISO</organization> </author> <dateyear="2006"/>year="2006" month="February"/> </front> <seriesInfoname="ISO/IEC 22537:2006" value=""/>name="ISO/IEC" value="22537:2006"/> <refcontent>Withdrawn</refcontent> <annotation>An equivalent specification, also withdrawn, is available from <eref target="https://ecma-international.org/publications-and-standards/standards/ecma-357" brackets="angle"/>.</annotation> </reference> <reference anchor="SLICE" target="https://github.com/tc39/proposal-slice-notation"> <front> <title>Slice notation</title> <author> <organization/> </author><date>n.d.</date><date month="July" year="2022"/> </front> <refcontent>commit 82f95b4</refcontent> </reference> <reference anchor="ECMA-262" target="https://www.ecma-international.org/wp-content/uploads/ECMA-262_3rd_edition_december_1999.pdf"> <front> <title>ECMAScript LanguageSpecification, Standard ECMA-262, Third Edition</title>Specification</title> <author><organization>Ecma<organization>ECMA International</organization> </author> <date year="1999" month="December"/> </front> <refcontent>Standard ECMA-262, Third Edition</refcontent> </reference><reference anchor="RFC8949"> <front> <title>Concise Binary Object Representation (CBOR)</title> <author fullname="C. Bormann" initials="C." surname="Bormann"/> <author fullname="P. Hoffman" initials="P." surname="Hoffman"/> <date month="December" year="2020"/> <abstract> <t>The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. These design goals make it different from earlier binary serializations such as ASN.1 and MessagePack.</t> <t>This document obsoletes RFC 7049, providing editorial improvements, new details, and errata fixes while keeping full compatibility with the interchange 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><xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8949.xml"/> <reference anchor="BOOLEAN-LAWS"target="https://en.wikipedia.org/wiki/Boolean_algebra#Laws">target="https://en.wikipedia.org/w/index.php?title=Boolean_algebra&oldid=1191386550#Laws"> <front> <title>Booleanalgebra laws</title>algebra: Laws</title> <author> <organization/> </author><date>n.d.</date><date month="December" year="2023"/> </front> </reference> </references> </references><?line 2296?><section anchor="collected-abnf-grammars"> <name>Collected ABNFgrammars</name>Grammars</name> <t>This appendix collects the ABNF grammar from the ABNF passages used 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 defines the syntax of a JSONPath query.</t> <figure anchor="jsonpath-abnf"> <name>Collected ABNF of JSONPathqueries</name>Queries</name> <sourcecode type="abnf"><![CDATA[ jsonpath-query = root-identifier segments segments = *(S segment) B = %x20 / ; Space %x09 / ; Horizontal tab %x0A / ; Line feed or New line %x0D ; Carriage return S = *B ; optional blank space root-identifier = "$" selector = name-selector / wildcard-selector / slice-selector / index-selector / filter-selector name-selector = string-literal string-literal = %x22 *double-quoted %x22 / ; "string" %x27 *single-quoted %x27 ; 'string' double-quoted = unescaped / %x27 / ; ' ESC %x22 / ; \" ESC escapable single-quoted = unescaped / %x22 / ; " ESC %x27 / ; \' ESC escapable ESC = %x5C ; \ backslash unescaped = %x20-21 / ; see RFC 8259 ; omit 0x22 " %x23-26 / ; omit 0x27 ' %x28-5B / ; omit 0x5C \ %x5D-D7FF / ; skip surrogate code points %xE000-10FFFF escapable = %x62 / ; b BS backspace U+0008 %x66 / ; f FF form feed U+000C %x6E / ; n LF line feed U+000A %x72 / ; r CR carriage return U+000D %x74 / ; t HT horizontal tab U+0009 "/" / ; / slash (solidus) U+002F "\" / ; \ backslash (reverse solidus) U+005C (%x75 hexchar) ; uXXXX U+XXXX hexchar = non-surrogate / (high-surrogate "\" %x75 low-surrogate) non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / ("D" %x30-37 2HEXDIG ) high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" wildcard-selector = "*" index-selector = int ; decimal integer int = "0" / (["-"] DIGIT1 *DIGIT) ; - optional DIGIT1 = %x31-39 ; 1-9 non-zero digit slice-selector = [start S] ":" S [end S] [":" [S step ]] start = int ; included in selection end = int ; not included in selection step = int ; default: 1 filter-selector = "?" S logical-expr logical-expr = logical-or-expr logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) ; disjunction ; binds less tightly than conjunction logical-and-expr = basic-expr *(S "&&" S basic-expr) ; conjunction ; binds more tightly than disjunction basic-expr = paren-expr / comparison-expr / test-expr paren-expr = [logical-not-op S] "(" S logical-expr S ")" ; parenthesized expression logical-not-op = "!" ; logical NOT operator test-expr = [logical-not-op S] (filter-query / ; existence/non-existence function-expr) ; LogicalType or NodesType filter-query = rel-query / jsonpath-query rel-query = current-node-identifier segments current-node-identifier = "@" comparison-expr = comparable S comparison-op S comparable literal = number / string-literal / true / false / null comparable = literal / singular-query / ; singular query value function-expr ; ValueType comparison-op = "==" / "!=" / "<=" / ">=" / "<" / ">" singular-query = rel-singular-query / abs-singular-query rel-singular-query = current-node-identifier singular-query-segments abs-singular-query = root-identifier singular-query-segments singular-query-segments = *(S (name-segment / index-segment)) name-segment = ("[" name-selector "]") / ("." member-name-shorthand) index-segment = "[" index-selector "]" number = (int / "-0") [ frac ] [ exp ] ; decimal number frac = "." 1*DIGIT ; decimal fraction exp = "e" [ "-" / "+" ] 1*DIGIT ; decimal exponent true = %x74.72.75.65 ; true false = %x66.61.6c.73.65 ; false null = %x6e.75.6c.6c ; null function-name = function-name-first *function-name-char function-name-first = LCALPHA function-name-char = function-name-first / "_" / DIGIT LCALPHA = %x61-7A ; "a".."z" function-expr = function-name "(" S [function-argument *(S "," S function-argument)] S ")" function-argument = literal / filter-query / ; (includes singular-query) logical-expr / function-expr segment = child-segment / descendant-segment child-segment = bracketed-selection / ("." (wildcard-selector / member-name-shorthand)) bracketed-selection = "[" S selector *(S "," S selector) S "]" member-name-shorthand = name-first *name-char name-first = ALPHA / "_" / %x80-D7FF / ; skip surrogate code points %xE000-10FFFF name-char =DIGIT /name-first / DIGIT DIGIT = %x30-39 ; 0-9 ALPHA = %x41-5A / %x61-7A ; A-Z / a-z descendant-segment = ".." (bracketed-selection / wildcard-selector / member-name-shorthand) ]]></sourcecode> </figure> <t><xref target="normalized-path-abnf"/> contains the collected ABNF grammar that defines the syntax of a JSONPath NormalizedPath,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> <figure anchor="normalized-path-abnf"> <name>Collected ABNF of JSONPath Normalized Paths</name> <sourcecode type="abnf"><![CDATA[ normalized-path = root-identifier *(normal-index-segment) normal-index-segment = "[" normal-selector "]" normal-selector = normal-name-selector / normal-index-selector normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' normal-single-quoted = normal-unescaped / ESC normal-escapable normal-unescaped = ; omit %x0-1F control codes %x20-26 / ; omit 0x27 ' %x28-5B / ; omit 0x5C \ %x5D-D7FF / ; skip surrogate code points %xE000-10FFFF normal-escapable = %x62 / ; b BS backspace U+0008 %x66 / ; f FF form feed U+000C %x6E / ; n LF line feed U+000A %x72 / ; r CR carriage return U+000D %x74 / ; t HT horizontal tab U+0009 "'" / ; ' apostrophe U+0027 "\" / ; \ backslash (reverse solidus) U+005C (%x75 normal-hexchar) ; certain values u00xx U+00XX normal-hexchar = "0" "0" ( ("0" %x30-37) / ; "00"-"07" ; omit U+0008-U+000A BS HT LF ("0" %x62) / ; "0b" ; omit U+000C-U+000D FF CR ("0" %x65-66) / ; "0e"-"0f" ("1" normal-HEXDIG) ) normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" normal-index-selector = "0" / (DIGIT1 *DIGIT) ; non-negative decimal integer ]]></sourcecode> </figure> </section> <section anchor="inspired-by-xpath"> <name>Inspired by XPath</name> <t>This appendix is informative.</t> <t>At the time JSONPath was invented, XML was noted for the availability of powerful tools to analyze,transformtransform, and selectively extract data from XML documents. <xref target="XPath"/> is one of these tools.</t> <t>In 2007, the need for something solving the same class of problems for the emerging JSON community became apparent, specifically for:</t> <ul spacing="normal"><li>Finding<li>finding data interactively and extracting them out of<xref target="RFC8259"/>JSON values <xref target="RFC8259"/> without specialscripting.</li> <li>Specifyingscripting and</li> <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, minimizing bandwidth usage.</li> </ul> <t>(Note: XPath has evolved since 2007, and recent versions even nominally support operating inside JSON values. This appendix only discusses the more widely used version of XPath that was available in 2007.)</t> <t>JSONPath picks up the overall feeling ofXPath,XPath but maps the concepts to syntax (and partially semantics) that would be familiar to someone using JSON in a dynamic language.</t><t>E.g.,<t>For example, in popular dynamic programming languages such as JavaScript,PythonPython, and PHP, the semantics of the XPathexpression</t>expression:</t> <sourcecode type="xpath"><![CDATA[ /store/book[1]/title ]]></sourcecode> <t>can be realized in theexpression</t>expression:</t> <sourcecode type="xpath"><![CDATA[ x.store.book[0].title ]]></sourcecode><t>or,<t>or in bracketnotation,</t>notation:</t> <sourcecode type="xpath"><![CDATA[ x['store']['book'][0]['title'] ]]></sourcecode> <t>with the variable x holding the query argument.</t> <t>The JSONPath language was designed to:</t> <ul spacing="normal"> <li>be naturally based on those languagecharacteristics;</li>characteristics,</li> <li>cover only the most essential parts of XPath1.0;</li>1.0,</li> <li>be lightweight in code size and memoryconsumption;</li>consumption, and</li> <li>be runtime efficient.</li> </ul> <section anchor="xpath-overview"> <name>JSONPath and XPath</name> <t>JSONPath expressions apply to JSON values in the same way 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, similar to XPath's <tt>/</tt> at the front.</t> <t>JSONPath expressions move further down the hierarchy using <em>dot notation</em> (<tt>$.store.book[0].title</tt>) or the <em>bracket notation</em>(<tt>$['store']['book'][0]['title']</tt>), a lightweight/limited, and a more heavyweight syntax replacing(<tt>$['store']['book'][0]['title']</tt>); both replace XPath's <tt>/</tt> within queryexpressions.</t>expressions, where <em>dot notation</em> serves as a lightweight but limited 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.TheJSONPath's descendantoperators,segment notation, starting with <tt>..</tt>, borrowed from <xref target="E4X"/>,areis similar to XPath's <tt>//</tt>. The array slicing construct <tt>[start:end:step]</tt> is unique to JSONPath, inspired by <xref target="SLICE"/> from ECMASCRIPT 4.</t> <t>Filter expressions are supported via the syntax <tt>?<logical-expr></tt> asin</t>in:</t> <sourcecodetype="JSONPath"><![CDATA[type="application/jsonpath"><![CDATA[ $.store.book[?@.price < 10].title ]]></sourcecode> <t><xref target="tbl-xpath-overview"/> extends <xref target="tbl-overview"/> by providing a comparison with similar XPath concepts.</t> <table anchor="tbl-xpath-overview"> <name>XPathsyntax comparedSyntax Compared to JSONPath</name> <thead> <tr> <th align="left">XPath</th> <th align="left">JSONPath</th> <th align="left">Description</th> </tr> </thead> <tbody> <tr> <td align="left"> <tt>/</tt></td> <td align="left"> <tt>$</tt></td> <td align="left">the root XML element</td> </tr> <tr> <td align="left"> <tt>.</tt></td> <td align="left"> <tt>@</tt></td> <td align="left">the current XML element</td> </tr> <tr> <td align="left"> <tt>/</tt></td> <td align="left"> <tt>.</tt> or <tt>[]</tt></td> <td align="left">child operator</td> </tr> <tr> <td align="left"> <tt>..</tt></td> <td align="left">n/a</td> <td align="left">parent operator</td> </tr> <tr> <td align="left"> <tt>//</tt></td> <td align="left"> <tt>..name</tt>,<tt>..[index]</tt>,<tt>..&wj;[index]</tt>, <tt>..*</tt>, or <tt>..[*]</tt></td> <td align="left">descendants (JSONPath borrows this syntax from E4X)</td> </tr> <tr> <td align="left"> <tt>*</tt></td> <td align="left"> <tt>*</tt></td> <td align="left">wildcard: All XML elements regardless of their names</td> </tr> <tr> <td align="left"> <tt>@</tt></td> <td align="left">n/a</td> <td align="left">attribute access: JSON values do not have attributes</td> </tr> <tr> <td align="left"> <tt>[]</tt></td> <td align="left"> <tt>[]</tt></td> <td align="left">subscript operator used to iterate over XML element collections and for predicates</td> </tr> <tr> <td align="left"> <tt>|</tt></td> <td align="left"> <tt>[,]</tt></td> <td align="left">Union operator (results in a combination of node sets); called list operator in JSONPath, allows combining member names, array indices, and slices</td> </tr> <tr> <td align="left">n/a</td> <td align="left"> <tt>[start:end:step]</tt></td> <td align="left">array slice operator borrowed from ES4</td> </tr> <tr> <td align="left"> <tt>[]</tt></td> <td align="left"> <tt>?</tt></td> <td align="left">applies a filter (script) expression</td> </tr> <tr> <td align="left">seamless</td> <td align="left">n/a</td> <td align="left">expression engine</td> </tr> <tr> <td align="left"> <tt>()</tt></td> <td align="left">n/a</td> <td align="left">grouping</td> </tr> </tbody> </table><!-- Note: the weirdness about the vertical bar above is intentional --><t>For further illustration, <xref target="tbl-xpath-equivalents"/> shows some XPath expressions and their JSONPath equivalents.</t> <table anchor="tbl-xpath-equivalents"> <name>Example XPathexpressionsExpressions andtheirTheir JSONPathequivalents</name>Equivalents</name> <thead> <tr> <th align="left">XPath</th> <th align="left">JSONPath</th> <th align="left">Result</th> </tr> </thead> <tbody> <tr> <td align="left"> <tt>/store/book/author</tt></td> <td align="left"> <tt>$.store.book[*].author</tt></td> <td align="left">the authors of all books in the store</td> </tr> <tr> <td align="left"> <tt>//author</tt></td> <td align="left"> <tt>$..author</tt></td> <td align="left">all authors</td> </tr> <tr> <td align="left"> <tt>/store/*</tt></td> <td align="left"> <tt>$.store.*</tt></td> <td align="left">all things in store, which are some books and a red bicycle</td> </tr> <tr> <td align="left"> <tt>/store//price</tt></td> <td align="left"> <tt>$.store..price</tt></td> <td align="left">the prices of everything in the store</td> </tr> <tr> <td align="left"> <tt>//book[3]</tt></td> <td align="left"> <tt>$..book[2]</tt></td> <td align="left">the third book</td> </tr> <tr> <td align="left"> <tt>//book[last()]</tt></td> <td align="left"> <tt>$..book[-1]</tt></td> <td align="left">the last book in order</td> </tr> <tr> <td align="left"><tt>//book[position()<3]</tt></td><tt>//&wj;book[position()<3]</tt></td> <td align="left"> <tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> <td align="left">the first two books</td> </tr> <tr> <td align="left"> <tt>//book[isbn]</tt></td> <td align="left"> <tt>$..book[?@.isbn]</tt></td> <td align="left">filter all books withisbnan ISBN number</td> </tr> <tr> <td align="left"> <tt>//book[price<10]</tt></td> <td align="left"> <tt>$..book[?@.price<10]</tt></td> <td align="left">filter all books cheaper than 10</td> </tr> <tr> <td align="left"> <tt>//*</tt></td> <td align="left"> <tt>$..*</tt></td> <td align="left">all elements in an XML document; all member values and array elements contained in input value</td> </tr> </tbody> </table> <t>XPath has a lot more functionality (location paths in unabbreviated syntax,operatorsoperators, and functions) than listed in this comparison. Moreover, there are significant differences in how the subscript operator works in XPath and JSONPath:</t> <ul spacing="normal"> <li>Square brackets in XPath expressions always operate on the <em>node set</em> resulting from the previous path fragment. Indices always start at 1.</li> <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 at 0.</li> </ul> </section> </section> <section anchor="json-pointer"> <name>JSON Pointer</name> <t>This appendix is informative.</t><t>JSONPath<t>In relation to JSON Pointer <xref target="RFC6901"/>, JSONPath is not intended as a replacementfor,but as a more powerfulcompanion to, JSON Pointer <xref target="RFC6901"/>.companion. The purposes of the two standards are different.</t> <t>JSON Pointer is for identifying a single value within a JSON value whose structure is known.</t> <t>JSONPath can identify a single value within a JSON value, forexampleexample, by 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 is known only in a general way.</t> <t>A Normalized JSONPath can be converted into a JSON Pointer by converting the syntax, without knowledge of any JSON value. The inverse is not generallytrue:true, i.e., a numeric reference token (path component) in a JSON Pointer may identify a member value of an object or an element of an array. For conversion to a JSONPath query, knowledge of the structure of the JSON value is needed to distinguish these cases.</t> </section> <section numbered="false" anchor="acknowledgements"> <name>Acknowledgements</name> <t>This document is based on <contact fullname="Stefan Gössner"/>'s original online article defining JSONPath <xref target="JSONPath-orig"/>.</t> <t>The books example was taken fromhttp://coli.lili.uni-bielefeld.de/~andreas/Seminare/sommer02/books.xml — a dead link now.</t>course material that Bielefeld University, Germany used in 2002.</t> <t>This work is indebted toChristoph Burgmer<contact fullname="Christoph Burgmer"/> for the superb JSONPath comparison project <xref target="COMPARISON"/>detailingthat details the behavior of over forty JSONPath implementations applied to numerous queries.</t><!-- LocalWords: JSONPath XPath nodelist memoization --></section> <section anchor="contributors" numbered="false"toc="include" removeInRFC="false">toc="include"> <name>Contributors</name> <contact initials="M." surname="Mikulicic" fullname="Marko Mikulicic"> <organization>InfluxData, Inc.</organization> <address> <postal> <city>Pisa</city><country>IT</country><country>Italy</country> </postal> <email>mmikulicic@gmail.com</email> </address> </contact> <contact initials="E." surname="Surov" fullname="Edward Surov"> <organization>TheSoul Publishing Ltd.</organization> <address> <postal> <city>Limassol</city> <country>Cyprus</country> </postal> <email>esurov.tsp@gmail.com</email> </address> </contact> <contact initials="G." surname="Dennis" fullname="Greg Dennis"> <organization/> <address> <postal> <city>Auckland</city> <country>New Zealand</country> </postal> <email>gregsdennis@yahoo.com</email> <uri>https://github.com/gregsdennis</uri> </address> </contact> </section> </back><!-- ##markdown-source: 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 AA== --></rfc>