rfc9535.original.xml | rfc9535.xml | |||
---|---|---|---|---|
<?xml version='1.0' encoding='utf-8'?> | <?xml version='1.0' encoding='utf-8'?> | |||
<!DOCTYPE rfc [ | <rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" ipr="trust200902" do | |||
<!ENTITY nbsp " "> | cName="draft-ietf-jsonpath-base-21" number="9535" submissionType="IETF" category | |||
<!ENTITY zwsp "​"> | ="std" consensus="true" xml:lang="en" tocDepth="4" tocInclude="true" sortRefs="t | |||
<!ENTITY nbhy "‑"> | rue" symRefs="true" updates="" obsoletes="" prepTime="2024-02-21T11:47:32" index | |||
<!ENTITY wj "⁠"> | Include="true" scripts="Common,Latin"> | |||
]> | <link href="https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base-21" rel= | |||
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> | "prev"/> | |||
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.43 (Ruby 3.2. | <link href="https://dx.doi.org/10.17487/rfc9535" rel="alternate"/> | |||
2) --> | <link href="urn:issn:2070-1721" rel="alternate"/> | |||
<?rfc comments="yes"?> | ||||
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft | ||||
-ietf-jsonpath-base-21" category="std" consensus="true" submissionType="IETF" xm | ||||
l:lang="en" tocDepth="4" tocInclude="true" sortRefs="true" symRefs="true" versio | ||||
n="3"> | ||||
<!-- xml2rfc v2v3 conversion 3.18.0 --> | ||||
<front> | <front> | |||
<title abbrev="JSONPath">JSONPath: Query expressions for JSON</title> | <title abbrev="JSONPath">JSONPath: Query Expressions for JSON</title> | |||
<seriesInfo name="Internet-Draft" value="draft-ietf-jsonpath-base-21"/> | <seriesInfo name="RFC" value="9535" stream="IETF"/> | |||
<author initials="S." surname="Gössner" fullname="Stefan Gössner" role="edit or"> | <author initials="S." surname="Gössner" fullname="Stefan Gössner" role="edit or"> | |||
<organization>Fachhochschule Dortmund</organization> | <organization showOnFrontPage="true">Fachhochschule Dortmund</organization > | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street>Sonnenstraße 96</street> | <street>Sonnenstraße 96</street> | |||
<city>Dortmund</city> | <city>Dortmund</city> | |||
<code>D-44139</code> | <code>D-44139</code> | |||
<country>Germany</country> | <country>Germany</country> | |||
</postal> | </postal> | |||
<email>stefan.goessner@fh-dortmund.de</email> | <email>stefan.goessner@fh-dortmund.de</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author initials="G." surname="Normington" fullname="Glyn Normington" role=" editor"> | <author initials="G." surname="Normington" fullname="Glyn Normington" role=" editor"> | |||
<organization/> | <organization showOnFrontPage="true"/> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street/> | <street/> | |||
<city>Winchester</city> | <city>Winchester</city> | |||
<region/> | <region/> | |||
<code/> | <code/> | |||
<country>UK</country> | <country>United Kingdom</country> | |||
</postal> | </postal> | |||
<phone/> | <phone/> | |||
<email>glyn.normington@gmail.com</email> | <email>glyn.normington@gmail.com</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<author initials="C." surname="Bormann" fullname="Carsten Bormann" role="edi tor"> | <author initials="C." surname="Bormann" fullname="Carsten Bormann" role="edi tor"> | |||
<organization>Universität Bremen TZI</organization> | <organization showOnFrontPage="true">Universität Bremen TZI</organization> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<street>Postfach 330440</street> | <street>Postfach 330440</street> | |||
<city>Bremen</city> | <city>Bremen</city> | |||
<code>D-28359</code> | <code>D-28359</code> | |||
<country>Germany</country> | <country>Germany</country> | |||
</postal> | </postal> | |||
<phone>+49-421-218-63921</phone> | <phone>+49-421-218-63921</phone> | |||
<email>cabo@tzi.org</email> | <email>cabo@tzi.org</email> | |||
</address> | </address> | |||
</author> | </author> | |||
<date year="2023"/> | <date month="02" year="2024"/> | |||
<area>ART</area> | <area>art</area> | |||
<workgroup>JSONPath WG</workgroup> | <workgroup>jsonpath</workgroup> | |||
<keyword>JSON</keyword> | <keyword>JSON</keyword> | |||
<abstract> | <abstract pn="section-abstract"> | |||
<?line 145?> | <t indent="0" pn="section-abstract-1">JSONPath defines a string syntax for | |||
selecting and extracting JSON (RFC 8259) values from within a given JSON value. | ||||
<t>JSONPath defines a string syntax for selecting and extracting JSON (RFC 8259) | </t> | |||
values | ||||
from a JSON value.</t> | ||||
</abstract> | </abstract> | |||
<note removeInRFC="true"> | <boilerplate> | |||
<name>About This Document</name> | <section anchor="status-of-memo" numbered="false" removeInRFC="false" toc= | |||
<t> | "exclude" pn="section-boilerplate.1"> | |||
Status information for this document may be found at <eref target="https | <name slugifiedName="name-status-of-this-memo">Status of This Memo</name | |||
://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/"/>. | > | |||
</t> | <t indent="0" pn="section-boilerplate.1-1"> | |||
<t> | This is an Internet Standards Track document. | |||
Discussion of this document takes place on the | </t> | |||
JSON Path Working Group mailing list (<eref target="mailto:jsonpath@ietf | <t indent="0" pn="section-boilerplate.1-2"> | |||
.org"/>), | This document is a product of the Internet Engineering Task Force | |||
which is archived at <eref target="https://mailarchive.ietf.org/arch/bro | (IETF). It represents the consensus of the IETF community. It has | |||
wse/jsonpath/"/>. | received public review and has been approved for publication by | |||
Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/jsonpat | the Internet Engineering Steering Group (IESG). Further | |||
h/"/>. | information on Internet Standards is available in Section 2 of | |||
</t> | RFC 7841. | |||
<t>Source for this draft and an issue tracker can be found at | </t> | |||
<eref target="https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-ba | <t indent="0" pn="section-boilerplate.1-3"> | |||
se"/>.</t> | Information about the current status of this document, any | |||
</note> | errata, and how to provide feedback on it may be obtained at | |||
<eref target="https://www.rfc-editor.org/info/rfc9535" brackets="non | ||||
e"/>. | ||||
</t> | ||||
</section> | ||||
<section anchor="copyright" numbered="false" removeInRFC="false" toc="excl | ||||
ude" pn="section-boilerplate.2"> | ||||
<name slugifiedName="name-copyright-notice">Copyright Notice</name> | ||||
<t indent="0" pn="section-boilerplate.2-1"> | ||||
Copyright (c) 2024 IETF Trust and the persons identified as the | ||||
document authors. All rights reserved. | ||||
</t> | ||||
<t indent="0" pn="section-boilerplate.2-2"> | ||||
This document is subject to BCP 78 and the IETF Trust's Legal | ||||
Provisions Relating to IETF Documents | ||||
(<eref target="https://trustee.ietf.org/license-info" brackets="none | ||||
"/>) in effect on the date of | ||||
publication of this document. Please review these documents | ||||
carefully, as they describe your rights and restrictions with | ||||
respect to this document. Code Components extracted from this | ||||
document must include Revised BSD License text as described in | ||||
Section 4.e of the Trust Legal Provisions and are provided without | ||||
warranty as described in the Revised BSD License. | ||||
</t> | ||||
</section> | ||||
</boilerplate> | ||||
<toc> | ||||
<section anchor="toc" numbered="false" removeInRFC="false" toc="exclude" p | ||||
n="section-toc.1"> | ||||
<name slugifiedName="name-table-of-contents">Table of Contents</name> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="section-to | ||||
c.1-1"> | ||||
<li pn="section-toc.1-1.1"> | ||||
<t indent="0" pn="section-toc.1-1.1.1"><xref derivedContent="1" form | ||||
at="counter" sectionFormat="of" target="section-1"/>. <xref derivedContent="" f | ||||
ormat="title" sectionFormat="of" target="name-introduction">Introduction</xref>< | ||||
/t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="sectio | ||||
n-toc.1-1.1.2"> | ||||
<li pn="section-toc.1-1.1.2.1"> | ||||
<t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.1.1">< | ||||
xref derivedContent="1.1" format="counter" sectionFormat="of" target="section-1. | ||||
1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-te | ||||
rminology">Terminology</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.1.2.1.2"> | ||||
<li pn="section-toc.1-1.1.2.1.2.1"> | ||||
<t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.1. | ||||
2.1.1"><xref derivedContent="1.1.1" format="counter" sectionFormat="of" target=" | ||||
section-1.1.1"/>. <xref derivedContent="" format="title" sectionFormat="of" tar | ||||
get="name-json-values-as-trees-of-nod">JSON Values as Trees of Nodes</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.2"> | ||||
<t indent="0" keepWithNext="true" pn="section-toc.1-1.1.2.2.1">< | ||||
xref derivedContent="1.2" format="counter" sectionFormat="of" target="section-1. | ||||
2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="name-hi | ||||
story">History</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.3.1"><xref derivedContent= | ||||
"1.3" format="counter" sectionFormat="of" target="section-1.3"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-json-values">JSON Valu | ||||
es</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.4"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.4.1"><xref derivedContent= | ||||
"1.4" format="counter" sectionFormat="of" target="section-1.4"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-overview-of-jsonpath-e | ||||
xpres">Overview of JSONPath Expressions</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.1.2.4.2"> | ||||
<li pn="section-toc.1-1.1.2.4.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.4.2.1.1"><xref derived | ||||
Content="1.4.1" format="counter" sectionFormat="of" target="section-1.4.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-identifier | ||||
s">Identifiers</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.4.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.4.2.2.1"><xref derived | ||||
Content="1.4.2" format="counter" sectionFormat="of" target="section-1.4.2"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-segments"> | ||||
Segments</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.4.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.4.2.3.1"><xref derived | ||||
Content="1.4.3" format="counter" sectionFormat="of" target="section-1.4.3"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-selectors" | ||||
>Selectors</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.4.2.4"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.4.2.4.1"><xref derived | ||||
Content="1.4.4" format="counter" sectionFormat="of" target="section-1.4.4"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-summary">S | ||||
ummary</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.1.2.5"> | ||||
<t indent="0" pn="section-toc.1-1.1.2.5.1"><xref derivedContent= | ||||
"1.5" format="counter" sectionFormat="of" target="section-1.5"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-jsonpath-examples">JSO | ||||
NPath Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.1"><xref derivedContent="2" form | ||||
at="counter" sectionFormat="of" target="section-2"/>. <xref derivedContent="" f | ||||
ormat="title" sectionFormat="of" target="name-jsonpath-syntax-and-semanti">JSONP | ||||
ath Syntax and Semantics</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="sectio | ||||
n-toc.1-1.2.2"> | ||||
<li pn="section-toc.1-1.2.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.1.1"><xref derivedContent= | ||||
"2.1" format="counter" sectionFormat="of" target="section-2.1"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-overview">Overview</xr | ||||
ef></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.1.2"> | ||||
<li pn="section-toc.1-1.2.2.1.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.1.2.1.1"><xref derived | ||||
Content="2.1.1" format="counter" sectionFormat="of" target="section-2.1.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-syntax">Sy | ||||
ntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.1.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.1.2.2.1"><xref derived | ||||
Content="2.1.2" format="counter" sectionFormat="of" target="section-2.1.2"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-semantics" | ||||
>Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.1.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.1.2.3.1"><xref derived | ||||
Content="2.1.3" format="counter" sectionFormat="of" target="section-2.1.3"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-example">E | ||||
xample</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.2.1"><xref derivedContent= | ||||
"2.2" format="counter" sectionFormat="of" target="section-2.2"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-root-identifier">Root | ||||
Identifier</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.2.2"> | ||||
<li pn="section-toc.1-1.2.2.2.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.2.2.1.1"><xref derived | ||||
Content="2.2.1" format="counter" sectionFormat="of" target="section-2.2.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-syntax-2"> | ||||
Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.2.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.2.2.2.1"><xref derived | ||||
Content="2.2.2" format="counter" sectionFormat="of" target="section-2.2.2"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-semantics- | ||||
2">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.2.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.2.2.3.1"><xref derived | ||||
Content="2.2.3" format="counter" sectionFormat="of" target="section-2.2.3"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-examples"> | ||||
Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.1"><xref derivedContent= | ||||
"2.3" format="counter" sectionFormat="of" target="section-2.3"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-selectors-2">Selectors | ||||
</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.3.2"> | ||||
<li pn="section-toc.1-1.2.2.3.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.1.1"><xref derived | ||||
Content="2.3.1" format="counter" sectionFormat="of" target="section-2.3.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-name-selec | ||||
tor">Name Selector</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.3.2.1.2"> | ||||
<li pn="section-toc.1-1.2.2.3.2.1.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.1.2.1.1"><xref | ||||
derivedContent="2.3.1.1" format="counter" sectionFormat="of" target="section-2. | ||||
3.1.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-3">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.1.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.1.2.2.1"><xref | ||||
derivedContent="2.3.1.2" format="counter" sectionFormat="of" target="section-2. | ||||
3.1.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-3">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.1.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.1.2.3.1"><xref | ||||
derivedContent="2.3.1.3" format="counter" sectionFormat="of" target="section-2. | ||||
3.1.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-2">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.2.1"><xref derived | ||||
Content="2.3.2" format="counter" sectionFormat="of" target="section-2.3.2"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-wildcard-s | ||||
elector">Wildcard Selector</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.3.2.2.2"> | ||||
<li pn="section-toc.1-1.2.2.3.2.2.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.2.2.1.1"><xref | ||||
derivedContent="2.3.2.1" format="counter" sectionFormat="of" target="section-2. | ||||
3.2.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-4">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.2.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.2.2.2.1"><xref | ||||
derivedContent="2.3.2.2" format="counter" sectionFormat="of" target="section-2. | ||||
3.2.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-4">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.2.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.2.2.3.1"><xref | ||||
derivedContent="2.3.2.3" format="counter" sectionFormat="of" target="section-2. | ||||
3.2.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-3">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.3.1"><xref derived | ||||
Content="2.3.3" format="counter" sectionFormat="of" target="section-2.3.3"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-index-sele | ||||
ctor">Index Selector</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.3.2.3.2"> | ||||
<li pn="section-toc.1-1.2.2.3.2.3.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.3.2.1.1"><xref | ||||
derivedContent="2.3.3.1" format="counter" sectionFormat="of" target="section-2. | ||||
3.3.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-5">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.3.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.3.2.2.1"><xref | ||||
derivedContent="2.3.3.2" format="counter" sectionFormat="of" target="section-2. | ||||
3.3.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-5">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.3.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.3.2.3.1"><xref | ||||
derivedContent="2.3.3.3" format="counter" sectionFormat="of" target="section-2. | ||||
3.3.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-4">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.4"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.4.1"><xref derived | ||||
Content="2.3.4" format="counter" sectionFormat="of" target="section-2.3.4"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-array-slic | ||||
e-selector">Array Slice Selector</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.3.2.4.2"> | ||||
<li pn="section-toc.1-1.2.2.3.2.4.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.4.2.1.1"><xref | ||||
derivedContent="2.3.4.1" format="counter" sectionFormat="of" target="section-2. | ||||
3.4.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-6">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.4.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.4.2.2.1"><xref | ||||
derivedContent="2.3.4.2" format="counter" sectionFormat="of" target="section-2. | ||||
3.4.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-6">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.4.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.4.2.3.1"><xref | ||||
derivedContent="2.3.4.3" format="counter" sectionFormat="of" target="section-2. | ||||
3.4.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-5">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.5"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.5.1"><xref derived | ||||
Content="2.3.5" format="counter" sectionFormat="of" target="section-2.3.5"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-filter-sel | ||||
ector">Filter Selector</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.3.2.5.2"> | ||||
<li pn="section-toc.1-1.2.2.3.2.5.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.5.2.1.1"><xref | ||||
derivedContent="2.3.5.1" format="counter" sectionFormat="of" target="section-2. | ||||
3.5.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-7">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.5.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.5.2.2.1"><xref | ||||
derivedContent="2.3.5.2" format="counter" sectionFormat="of" target="section-2. | ||||
3.5.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-7">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.3.2.5.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.3.2.5.2.3.1"><xref | ||||
derivedContent="2.3.5.3" format="counter" sectionFormat="of" target="section-2. | ||||
3.5.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-6">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.1"><xref derivedContent= | ||||
"2.4" format="counter" sectionFormat="of" target="section-2.4"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-function-extensions">F | ||||
unction Extensions</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.4.2"> | ||||
<li pn="section-toc.1-1.2.2.4.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.1.1"><xref derived | ||||
Content="2.4.1" format="counter" sectionFormat="of" target="section-2.4.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-type-syste | ||||
m-for-function-ex">Type System for Function Expressions</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.2.1"><xref derived | ||||
Content="2.4.2" format="counter" sectionFormat="of" target="section-2.4.2"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-type-conve | ||||
rsion">Type Conversion</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.3.1"><xref derived | ||||
Content="2.4.3" format="counter" sectionFormat="of" target="section-2.4.3"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-well-typed | ||||
ness-of-function-">Well-Typedness of Function Expressions</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.4"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.4.1"><xref derived | ||||
Content="2.4.4" format="counter" sectionFormat="of" target="section-2.4.4"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-length-fun | ||||
ction-extension"><tt>length()</tt> Function Extension</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.5"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.5.1"><xref derived | ||||
Content="2.4.5" format="counter" sectionFormat="of" target="section-2.4.5"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-count-func | ||||
tion-extension"><tt>count()</tt> Function Extension</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.6"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.6.1"><xref derived | ||||
Content="2.4.6" format="counter" sectionFormat="of" target="section-2.4.6"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-match-func | ||||
tion-extension"><tt>match()</tt> Function Extension</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.7"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.7.1"><xref derived | ||||
Content="2.4.7" format="counter" sectionFormat="of" target="section-2.4.7"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-search-fun | ||||
ction-extension"><tt>search()</tt> Function Extension</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.8"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.8.1"><xref derived | ||||
Content="2.4.8" format="counter" sectionFormat="of" target="section-2.4.8"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-value-func | ||||
tion-extension"><tt>value()</tt> Function Extension</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.4.2.9"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.4.2.9.1"><xref derived | ||||
Content="2.4.9" format="counter" sectionFormat="of" target="section-2.4.9"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-examples-7 | ||||
">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.5"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.1"><xref derivedContent= | ||||
"2.5" format="counter" sectionFormat="of" target="section-2.5"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-segments-2">Segments</ | ||||
xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.5.2"> | ||||
<li pn="section-toc.1-1.2.2.5.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.1.1"><xref derived | ||||
Content="2.5.1" format="counter" sectionFormat="of" target="section-2.5.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-child-segm | ||||
ent">Child Segment</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.5.2.1.2"> | ||||
<li pn="section-toc.1-1.2.2.5.2.1.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.1.2.1.1"><xref | ||||
derivedContent="2.5.1.1" format="counter" sectionFormat="of" target="section-2. | ||||
5.1.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-8">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.5.2.1.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.1.2.2.1"><xref | ||||
derivedContent="2.5.1.2" format="counter" sectionFormat="of" target="section-2. | ||||
5.1.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-8">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.5.2.1.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.1.2.3.1"><xref | ||||
derivedContent="2.5.1.3" format="counter" sectionFormat="of" target="section-2. | ||||
5.1.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-8">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.5.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.2.1"><xref derived | ||||
Content="2.5.2" format="counter" sectionFormat="of" target="section-2.5.2"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-descendant | ||||
-segment">Descendant Segment</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn | ||||
="section-toc.1-1.2.2.5.2.2.2"> | ||||
<li pn="section-toc.1-1.2.2.5.2.2.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.2.2.1.1"><xref | ||||
derivedContent="2.5.2.1" format="counter" sectionFormat="of" target="section-2. | ||||
5.2.1"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-syntax-9">Syntax</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.5.2.2.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.2.2.2.1"><xref | ||||
derivedContent="2.5.2.2" format="counter" sectionFormat="of" target="section-2. | ||||
5.2.2"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-semantics-9">Semantics</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.5.2.2.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.5.2.2.2.3.1"><xref | ||||
derivedContent="2.5.2.3" format="counter" sectionFormat="of" target="section-2. | ||||
5.2.3"/>. <xref derivedContent="" format="title" sectionFormat="of" target="nam | ||||
e-examples-9">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.6"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.6.1"><xref derivedContent= | ||||
"2.6" format="counter" sectionFormat="of" target="section-2.6"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-semantics-of-null">Sem | ||||
antics of <tt>null</tt></xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.6.2"> | ||||
<li pn="section-toc.1-1.2.2.6.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.6.2.1.1"><xref derived | ||||
Content="2.6.1" format="counter" sectionFormat="of" target="section-2.6.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-examples-1 | ||||
0">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.2.2.7"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.7.1"><xref derivedContent= | ||||
"2.7" format="counter" sectionFormat="of" target="section-2.7"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-normalized-paths">Norm | ||||
alized Paths</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="se | ||||
ction-toc.1-1.2.2.7.2"> | ||||
<li pn="section-toc.1-1.2.2.7.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.2.2.7.2.1.1"><xref derived | ||||
Content="2.7.1" format="counter" sectionFormat="of" target="section-2.7.1"/>. < | ||||
xref derivedContent="" format="title" sectionFormat="of" target="name-examples-1 | ||||
1">Examples</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.3"> | ||||
<t indent="0" pn="section-toc.1-1.3.1"><xref derivedContent="3" form | ||||
at="counter" sectionFormat="of" target="section-3"/>. <xref derivedContent="" f | ||||
ormat="title" sectionFormat="of" target="name-iana-considerations">IANA Consider | ||||
ations</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="sectio | ||||
n-toc.1-1.3.2"> | ||||
<li pn="section-toc.1-1.3.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.3.2.1.1"><xref derivedContent= | ||||
"3.1" format="counter" sectionFormat="of" target="section-3.1"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-registration-of-media- | ||||
type-">Registration of Media Type application/jsonpath</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.3.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.3.2.2.1"><xref derivedContent= | ||||
"3.2" format="counter" sectionFormat="of" target="section-3.2"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-function-extensions-su | ||||
bregi">Function Extensions Subregistry</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.4"> | ||||
<t indent="0" pn="section-toc.1-1.4.1"><xref derivedContent="4" form | ||||
at="counter" sectionFormat="of" target="section-4"/>. <xref derivedContent="" f | ||||
ormat="title" sectionFormat="of" target="name-security-considerations">Security | ||||
Considerations</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="sectio | ||||
n-toc.1-1.4.2"> | ||||
<li pn="section-toc.1-1.4.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.4.2.1.1"><xref derivedContent= | ||||
"4.1" format="counter" sectionFormat="of" target="section-4.1"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-attack-vectors-on-json | ||||
path-">Attack Vectors on JSONPath Implementations</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.4.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.4.2.2.1"><xref derivedContent= | ||||
"4.2" format="counter" sectionFormat="of" target="section-4.2"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-attack-vectors-on-how- | ||||
jsonp">Attack Vectors on How JSONPath Queries Are Formed</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.4.2.3"> | ||||
<t indent="0" pn="section-toc.1-1.4.2.3.1"><xref derivedContent= | ||||
"4.3" format="counter" sectionFormat="of" target="section-4.3"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-attacks-on-security-me | ||||
chani">Attacks on Security Mechanisms That Employ JSONPath</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.5"> | ||||
<t indent="0" pn="section-toc.1-1.5.1"><xref derivedContent="5" form | ||||
at="counter" sectionFormat="of" target="section-5"/>. <xref derivedContent="" f | ||||
ormat="title" sectionFormat="of" target="name-references">References</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="sectio | ||||
n-toc.1-1.5.2"> | ||||
<li pn="section-toc.1-1.5.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.5.2.1.1"><xref derivedContent= | ||||
"5.1" format="counter" sectionFormat="of" target="section-5.1"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-normative-references"> | ||||
Normative References</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.5.2.2"> | ||||
<t indent="0" pn="section-toc.1-1.5.2.2.1"><xref derivedContent= | ||||
"5.2" format="counter" sectionFormat="of" target="section-5.2"/>. <xref derived | ||||
Content="" format="title" sectionFormat="of" target="name-informative-references | ||||
">Informative References</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.6"> | ||||
<t indent="0" pn="section-toc.1-1.6.1"><xref derivedContent="Appendi | ||||
x A" format="default" sectionFormat="of" target="section-appendix.a"/>. <xref d | ||||
erivedContent="" format="title" sectionFormat="of" target="name-collected-abnf-g | ||||
rammars">Collected ABNF Grammars</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.7"> | ||||
<t indent="0" pn="section-toc.1-1.7.1"><xref derivedContent="Appendi | ||||
x B" format="default" sectionFormat="of" target="section-appendix.b"/>. <xref d | ||||
erivedContent="" format="title" sectionFormat="of" target="name-inspired-by-xpat | ||||
h">Inspired by XPath</xref></t> | ||||
<ul bare="true" empty="true" indent="2" spacing="compact" pn="sectio | ||||
n-toc.1-1.7.2"> | ||||
<li pn="section-toc.1-1.7.2.1"> | ||||
<t indent="0" pn="section-toc.1-1.7.2.1.1"><xref derivedContent= | ||||
"B.1" format="counter" sectionFormat="of" target="section-appendix.b.1"/>. <xre | ||||
f derivedContent="" format="title" sectionFormat="of" target="name-jsonpath-and- | ||||
xpath">JSONPath and XPath</xref></t> | ||||
</li> | ||||
</ul> | ||||
</li> | ||||
<li pn="section-toc.1-1.8"> | ||||
<t indent="0" pn="section-toc.1-1.8.1"><xref derivedContent="Appendi | ||||
x C" format="default" sectionFormat="of" target="section-appendix.c"/>. <xref d | ||||
erivedContent="" format="title" sectionFormat="of" target="name-json-pointer">JS | ||||
ON Pointer</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.9"> | ||||
<t indent="0" pn="section-toc.1-1.9.1"><xref derivedContent="" forma | ||||
t="none" sectionFormat="of" target="section-appendix.d"/><xref derivedContent="" | ||||
format="title" sectionFormat="of" target="name-acknowledgements">Acknowledgemen | ||||
ts</xref></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.10"> | ||||
<t indent="0" pn="section-toc.1-1.10.1"><xref derivedContent="" form | ||||
at="none" sectionFormat="of" target="section-appendix.e"/><xref derivedContent=" | ||||
" format="title" sectionFormat="of" target="name-contributors">Contributors</xre | ||||
f></t> | ||||
</li> | ||||
<li pn="section-toc.1-1.11"> | ||||
<t indent="0" pn="section-toc.1-1.11.1"><xref derivedContent="" form | ||||
at="none" sectionFormat="of" target="section-appendix.f"/><xref derivedContent=" | ||||
" format="title" sectionFormat="of" target="name-authors-addresses">Authors' Add | ||||
resses</xref></t> | ||||
</li> | ||||
</ul> | ||||
</section> | ||||
</toc> | ||||
</front> | </front> | |||
<middle> | <middle> | |||
<?line 150?> | <section anchor="introduction" numbered="true" removeInRFC="false" toc="incl | |||
ude" pn="section-1"> | ||||
<!-- define an ALD to simplify below --> | <name slugifiedName="name-introduction">Introduction</name> | |||
<!-- use as {: unnumbered} --> | <t indent="0" pn="section-1-1">JSON <xref target="RFC8259" format="default | |||
" sectionFormat="of" derivedContent="RFC8259"/> is a popular representation | ||||
<!-- 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. | format for structured data values. | |||
JSONPath defines a string syntax for selecting and extracting JSON values | JSONPath defines a string syntax for selecting and extracting JSON values | |||
from a JSON value.</t> | from within a given JSON value.</t> | |||
<t>JSONPath is not intended as a replacement for, but as a more powerful | <t indent="0" pn="section-1-2">In relation to JSON Pointer <xref target="R | |||
companion to, JSON Pointer <xref target="RFC6901"/>. See <xref target="json-poin | FC6901" format="default" sectionFormat="of" derivedContent="RFC6901"/>, JSONPath | |||
ter"/>.</t> | is not intended as a replacement but as a more powerful | |||
<section anchor="terminology"> | companion. See <xref target="json-pointer" format="default" sectionFormat="of" d | |||
<name>Terminology</name> | erivedContent="Appendix C"/>.</t> | |||
<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp | <section anchor="terminology" numbered="true" removeInRFC="false" toc="inc | |||
14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | lude" pn="section-1.1"> | |||
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECO | <name slugifiedName="name-terminology">Terminology</name> | |||
MMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | <t indent="0" pn="section-1.1-1"> | |||
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be i | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU | |||
nterpreted as | IRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOUL | |||
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and | D</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>N | |||
only when, they | OT RECOMMENDED</bcp14>", | |||
appear in all capitals, as shown here.</t> | "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to | |||
<?line -18?> | be interpreted as | |||
described in BCP 14 <xref target="RFC2119" format="default" sectionFormat="o | ||||
<t>The grammatical rules in this document are to be interpreted as ABNF, | f" derivedContent="RFC2119"/> <xref target="RFC8174" format="default" sectionFor | |||
as described in <xref target="RFC5234"/>. | mat="of" derivedContent="RFC8174"/> | |||
when, and only when, they appear in all capitals, as shown here. | ||||
</t> | ||||
<t indent="0" pn="section-1.1-2">The grammatical rules in this document | ||||
are to be interpreted as ABNF, | ||||
as described in <xref target="RFC5234" format="default" sectionFormat="of" deriv | ||||
edContent="RFC5234"/>. | ||||
ABNF terminal values in this document define Unicode scalar values rather than | ABNF terminal values in this document define Unicode scalar values rather than | |||
their UTF-8 encoding. | their UTF-8 encoding. | |||
For example, the Unicode PLACE OF INTEREST SIGN (U+2318) would be defined | For example, the Unicode PLACE OF INTEREST SIGN (U+2318) would be defined | |||
in ABNF as <tt>%x2318</tt>.</t> | in ABNF as <tt>%x2318</tt>.</t> | |||
<t>Functions are referred to using the function name followed by a pair | <t indent="0" pn="section-1.1-3">Functions are referred to using the fun ction name followed by a pair | |||
of parentheses, as in <tt>fname()</tt>.</t> | of parentheses, as in <tt>fname()</tt>.</t> | |||
<t>The terminology of <xref target="RFC8259"/> applies except where clar | <t indent="0" pn="section-1.1-4">The terminology of <xref target="RFC825 | |||
ified below. | 9" format="default" sectionFormat="of" derivedContent="RFC8259"/> applies except | |||
The terms "Primitive" and "Structured" are used to group | where clarified below. | |||
different kinds of values as in <xref section="1" sectionFormat="of" target="RFC | The terms "primitive" and "structured" are used to group | |||
8259"/>; JSON Objects and Arrays are | different kinds of values as in <xref section="1" sectionFormat="of" target="RFC | |||
structured, all other values are primitive. | 8259" format="default" derivedLink="https://rfc-editor.org/rfc/rfc8259#section-1 | |||
Definitions for "Object", "Array", "Number", and "String" remain | " derivedContent="RFC8259"/>. JSON objects and arrays are | |||
structured; all other values are primitive. | ||||
Definitions for "object", "array", "number", and "string" remain | ||||
unchanged. | unchanged. | |||
Importantly "object" and "array" in particular do not take on a | Importantly, "object" and "array" in particular do not take on a | |||
generic meaning, such as they would in a general programming context.</t> | generic meaning, such as they would in a general programming context.</t> | |||
<t>Additional terms used in this document are defined below.</t> | <t indent="0" pn="section-1.1-5">The terminology of <xref target="RFC948 | |||
<dl> | 5" format="default" sectionFormat="of" derivedContent="RFC9485"/> applies.</t> | |||
<dt>Value:</dt> | <t indent="0" pn="section-1.1-6">Additional terms used in this document | |||
<dd> | are defined below.</t> | |||
<t>As per <xref target="RFC8259"/>, a structure conforming to the ge | <dl indent="3" newline="false" spacing="normal" pn="section-1.1-7"> | |||
neric data model of JSON, i.e., | <dt pn="section-1.1-7.1">Value:</dt> | |||
composed of constituents such as structured values, namely JSON objects and arra | <dd pn="section-1.1-7.2"> | |||
ys, and | <t indent="0" pn="section-1.1-7.2.1">As per <xref target="RFC8259" f | |||
primitive data, namely numbers and text strings as well as the special | ormat="default" sectionFormat="of" derivedContent="RFC8259"/>, a data item confo | |||
values null, true, and false. | rming to the generic data model of JSON, i.e., | |||
<xref target="RFC8259"/> focuses on the textual representation of JSON values an | primitive data (numbers, text strings, and the special | |||
d | values null, true, and false), or structured data (JSON objects and arrays). | |||
<xref target="RFC8259" format="default" sectionFormat="of" derivedContent="RFC82 | ||||
59"/> focuses on the textual representation of JSON values and | ||||
does not fully define the value abstraction assumed here.</t> | does not fully define the value abstraction assumed here.</t> | |||
</dd> | </dd> | |||
<dt>Member:</dt> | <dt pn="section-1.1-7.3">Member:</dt> | |||
<dd> | <dd pn="section-1.1-7.4"> | |||
<t>A name/value pair in an object. (A member is not itself a value. | <t indent="0" pn="section-1.1-7.4.1">A name/value pair in an object. | |||
)</t> | (A member is not itself a value.)</t> | |||
</dd> | </dd> | |||
<dt>Name:</dt> | <dt pn="section-1.1-7.5">Name:</dt> | |||
<dd> | <dd pn="section-1.1-7.6"> | |||
<t>The name (a string) in a name/value pair constituting a member. | <t indent="0" pn="section-1.1-7.6.1">The name (a string) in a name/v | |||
This is also used in <xref target="RFC8259"/>, but that specification does not | alue pair constituting a member. | |||
This is also used in <xref target="RFC8259" format="default" sectionFormat="of" | ||||
derivedContent="RFC8259"/>, but that specification does not | ||||
formally define it. | formally define it. | |||
It is included here for completeness.</t> | It is included here for completeness.</t> | |||
</dd> | </dd> | |||
<dt>Element:</dt> | <dt pn="section-1.1-7.7">Element:</dt> | |||
<dd> | <dd pn="section-1.1-7.8"> | |||
<t>A value in a JSON array.</t> | <t indent="0" pn="section-1.1-7.8.1">A value in a JSON array.</t> | |||
</dd> | </dd> | |||
<dt>Index:</dt> | <dt pn="section-1.1-7.9">Index:</dt> | |||
<dd> | <dd pn="section-1.1-7.10"> | |||
<t>An integer that identifies a specific element in an array.</t> | <t indent="0" pn="section-1.1-7.10.1">An integer that identifies a s | |||
pecific element in an array.</t> | ||||
</dd> | </dd> | |||
<dt>Query:</dt> | <dt pn="section-1.1-7.11">Query:</dt> | |||
<dd> | <dd pn="section-1.1-7.12"> | |||
<t>Short name for a JSONPath expression.</t> | <t indent="0" pn="section-1.1-7.12.1">Short name for a JSONPath expr | |||
ession.</t> | ||||
</dd> | </dd> | |||
<dt>Query Argument:</dt> | <dt pn="section-1.1-7.13">Query Argument:</dt> | |||
<dd> | <dd pn="section-1.1-7.14"> | |||
<t>Short name for the value a JSONPath expression is applied to. | <t indent="0" pn="section-1.1-7.14.1">Short name for the value a JSO | |||
(Also used for actual parameters of function-expressions.)</t> | NPath expression is applied to. | |||
</t> | ||||
</dd> | </dd> | |||
<dt>Location:</dt> | <dt pn="section-1.1-7.15">Location:</dt> | |||
<dd> | <dd pn="section-1.1-7.16"> | |||
<t>the position of a value within the query argument. This can be th | <t indent="0" pn="section-1.1-7.16.1">The position of a value within | |||
ought of | the query argument. This can be thought of | |||
as a sequence of names and indexes navigating to the value through | as a sequence of names and indexes navigating to the value through | |||
the objects and arrays in the query argument, with the empty sequence | the objects and arrays in the query argument, with the empty sequence | |||
indicating the query argument itself. | indicating the query argument itself. | |||
A location can be represented as a Normalized Path (defined below).</t> | A location can be represented as a Normalized Path (defined below).</t> | |||
</dd> | </dd> | |||
<dt>Node:</dt> | <dt pn="section-1.1-7.17">Node:</dt> | |||
<dd> | <dd pn="section-1.1-7.18"> | |||
<t>The pair of a value along with its location within the query argu | <t indent="0" pn="section-1.1-7.18.1">The pair of a value along with | |||
ment.</t> | its location within the query argument.</t> | |||
</dd> | </dd> | |||
<dt>Root Node:</dt> | <dt pn="section-1.1-7.19">Root Node:</dt> | |||
<dd> | <dd pn="section-1.1-7.20"> | |||
<t>The unique node whose value is the entire query argument.</t> | <t indent="0" pn="section-1.1-7.20.1">The unique node whose value is | |||
the entire query argument.</t> | ||||
</dd> | </dd> | |||
<dt>Root Node Identifier:</dt> | <dt pn="section-1.1-7.21">Root Node Identifier:</dt> | |||
<dd> | <dd pn="section-1.1-7.22"> | |||
<t>The expression <tt>$</tt> which refers to the root node of the qu | <t indent="0" pn="section-1.1-7.22.1">The expression <tt>$</tt>, whi | |||
ery argument.</t> | ch refers to the root node of the query argument.</t> | |||
</dd> | </dd> | |||
<dt>Current Node Identifier:</dt> | <dt pn="section-1.1-7.23">Current Node Identifier:</dt> | |||
<dd> | <dd pn="section-1.1-7.24"> | |||
<t>The expression <tt>@</tt> which refers to the current node in the | <t indent="0" pn="section-1.1-7.24.1">The expression <tt>@</tt>, whi | |||
context | ch refers to the current node in the context | |||
of the evaluation of a filter expression (described later).</t> | of the evaluation of a filter expression (described later).</t> | |||
</dd> | </dd> | |||
<dt>Children (of a node):</dt> | <dt pn="section-1.1-7.25">Children (of a node):</dt> | |||
<dd> | <dd pn="section-1.1-7.26"> | |||
<t>If the node is an array, the nodes of its elements. | <t indent="0" pn="section-1.1-7.26.1">If the node is an array, the n | |||
If the node is an object, the nodes of its member values. | odes of its elements; 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> | If the node is neither an array nor an object, it has no children.</t> | |||
</dd> | </dd> | |||
<dt>Descendants (of a node):</dt> | <dt pn="section-1.1-7.27">Descendants (of a node):</dt> | |||
<dd> | <dd pn="section-1.1-7.28"> | |||
<t>The children of the node, together with the children of its child | <t indent="0" pn="section-1.1-7.28.1">The children of the node, toge | |||
ren, and so forth | ther with the children of its children, and so forth | |||
recursively. More formally, the "descendants" relation between nodes is the tran sitive | recursively. More formally, the "descendants" relation between nodes is the tran sitive | |||
closure of the "children" relation.</t> | closure of the "children" relation.</t> | |||
</dd> | </dd> | |||
<dt>Depth (of a descendant node within a value):</dt> | <dt pn="section-1.1-7.29">Depth (of a descendant node within a value): | |||
<dd> | </dt> | |||
<t>The number of ancestors of the node within the value. The root no | <dd pn="section-1.1-7.30"> | |||
de of the value has depth zero, | <t indent="0" pn="section-1.1-7.30.1">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> | the children of the root node have depth one, their children have depth two, and so forth.</t> | |||
</dd> | </dd> | |||
<dt>Nodelist:</dt> | <dt pn="section-1.1-7.31">Nodelist:</dt> | |||
<dd> | <dd pn="section-1.1-7.32"> | |||
<t>A list of nodes. | <t indent="0" pn="section-1.1-7.32.1">A list of nodes. | |||
While a nodelist can be represented in JSON, e.g. as an array, this document | While a nodelist can be represented in JSON, e.g., as an array, this document | |||
does not require or assume any particular representation.</t> | does not require or assume any particular representation.</t> | |||
</dd> | </dd> | |||
<dt>Parameter:</dt> | <dt pn="section-1.1-7.33">Parameter:</dt> | |||
<dd> | <dd pn="section-1.1-7.34"> | |||
<t>Formal parameter (of a function) that can take a function argumen | <t indent="0" pn="section-1.1-7.34.1">Formal parameter (of a functio | |||
t | n) that can take a function argument | |||
(an actual parameter) in a function-expression.</t> | (an actual parameter) in a function expression.</t> | |||
</dd> | </dd> | |||
<dt>Normalized Path:</dt> | <dt pn="section-1.1-7.35">Normalized Path:</dt> | |||
<dd> | <dd pn="section-1.1-7.36"> | |||
<t>A form of JSONPath expression that identifies a node in a value b | <t indent="0" pn="section-1.1-7.36.1">A form of JSONPath expression | |||
y | that identifies a node in a value by | |||
providing a query that results in exactly that node. Each node in a | providing a query that results in exactly that node. Each node in a | |||
query argument is identified by exactly one Normalized Path (we say, the | query argument is identified by exactly one Normalized Path (we say that the | |||
Normalized Path is "unique" for that node), and, to be a Normalized | Normalized Path is "unique" for that node), and to be a Normalized | |||
Path for a specific query argument, the Normalized Path needs to identify | Path for a specific query argument, the Normalized Path needs to identify | |||
exactly one node. Similar | exactly one node. This is similar | |||
to, but syntactically different from, a JSON Pointer <xref target="RFC6901"/>. | to, but syntactically different from, a JSON Pointer <xref target="RFC6901" form | |||
Note: This definition is based on the syntactical definition in <xref target="no | at="default" sectionFormat="of" derivedContent="RFC6901"/>. | |||
rmalized-paths"/>; | Note: This definition is based on the syntactical definition in <xref target="no | |||
rmalized-paths" format="default" sectionFormat="of" derivedContent="Section 2.7" | ||||
/>; | ||||
JSONPath expressions that identify a node in a value but do not conform to that | JSONPath expressions that identify a node in a value but do not conform to that | |||
syntax are not Normalized Paths.</t> | syntax are not Normalized Paths.</t> | |||
</dd> | </dd> | |||
<dt>Unicode Scalar Value:</dt> | <dt pn="section-1.1-7.37">Unicode Scalar Value:</dt> | |||
<dd> | <dd pn="section-1.1-7.38"> | |||
<t>Any Unicode <xref target="UNICODE"/> code point except high-surro | <t indent="0" pn="section-1.1-7.38.1">Any Unicode <xref target="UNIC | |||
gate and low-surrogate code points. | ODE" format="default" sectionFormat="of" derivedContent="UNICODE"/> code point e | |||
In other words, integers in either of the inclusive base 16 ranges 0 to D7FF and | xcept high-surrogate and low-surrogate code points (in other words, integers in | |||
E000 to 10FFFF. JSONPath queries are sequences of Unicode scalar values.</t> | the inclusive base 16 ranges, either 0 to D7FF or | |||
E000 to 10FFFF). JSONPath queries are sequences of Unicode scalar values.</t> | ||||
</dd> | </dd> | |||
<dt>Segment:</dt> | <dt pn="section-1.1-7.39">Segment:</dt> | |||
<dd> | <dd pn="section-1.1-7.40"> | |||
<t>One of the constructs which select children (<tt>[<selectors&g | <t indent="0" pn="section-1.1-7.40.1">One of the constructs that sel | |||
t;]</tt>) | ects children (<tt>[<selectors>]</tt>) | |||
or descendants (<tt>..[<selectors>]</tt>) of an input value.</t> | or descendants (<tt>..[<selectors>]</tt>) of an input value.</t> | |||
</dd> | </dd> | |||
<dt>Selector:</dt> | <dt pn="section-1.1-7.41">Selector:</dt> | |||
<dd> | <dd pn="section-1.1-7.42"> | |||
<t>A single item within a segment that takes the input value and pro | <t indent="0" pn="section-1.1-7.42.1">A single item within a segment | |||
duces a nodelist | that takes the input value and produces a nodelist | |||
consisting of child nodes of the input value.</t> | consisting of child nodes of the input value.</t> | |||
</dd> | </dd> | |||
<dt>Singular Query:</dt> | <dt pn="section-1.1-7.43">Singular Query:</dt> | |||
<dd> | <dd pn="section-1.1-7.44"> | |||
<t>A JSONPath expression built from segments that have been syntacti | <t indent="0" pn="section-1.1-7.44.1">A JSONPath expression built fr | |||
cally restricted in | om segments that have been syntactically restricted in | |||
a certain way (<xref target="filter-selector-syntax"/>) so that, regardless of t | a certain way (<xref target="filter-selector-syntax" format="default" sectionFor | |||
he input | mat="of" derivedContent="Section 2.3.5.1"/>) so that, regardless of the input | |||
value, the expression produces a nodelist containing at most one node. | value, the expression produces a nodelist containing at most one node. | |||
Note: JSONPath expressions that always produce a singular nodelist but do not | Note: JSONPath expressions that always produce a singular nodelist but do not | |||
conform to the syntax in <xref target="filter-selector-syntax"/> are not Singula r Queries.</t> | conform to the syntax in <xref target="filter-selector-syntax" format="default" sectionFormat="of" derivedContent="Section 2.3.5.1"/> are not singular queries.< /t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<section anchor="json-values-as-trees-of-nodes"> | <section anchor="json-values-as-trees-of-nodes" numbered="true" removeIn | |||
<name>JSON Values as Trees of Nodes</name> | RFC="false" toc="include" pn="section-1.1.1"> | |||
<t>This document models the query argument as a tree of JSON values, e | <name slugifiedName="name-json-values-as-trees-of-nod">JSON Values as | |||
ach | Trees of Nodes</name> | |||
<t indent="0" pn="section-1.1.1-1">This document models the query argu | ||||
ment as a tree of JSON values, each | ||||
with its own node. | with its own node. | |||
A node is either the root node or one of its descendants.</t> | A node is either the root node or one of its descendants.</t> | |||
<t>This document models the result of applying a query to the | <t indent="0" pn="section-1.1.1-2">This document models the result of applying a query to the | |||
query argument as a nodelist (a list of nodes).</t> | query argument as a nodelist (a list of nodes).</t> | |||
<t>Nodes are the selectable parts of the query argument. | <t indent="0" pn="section-1.1.1-3">Nodes are the selectable parts of t he query argument. | |||
The only parts of an object that can be selected by a query are the | The only parts of an object that can be selected by a query are the | |||
member values. Member names and members (name/value pairs) cannot be | member values. Member names and members (name/value pairs) cannot be | |||
selected. | selected. | |||
Thus, member values have nodes, but members and member names do not. | Thus, member values have nodes, but members and member names do not. | |||
Similarly, member values are children of an object, but members and | Similarly, member values are children of an object, but members and | |||
member names are not.</t> | member names are not.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="history"> | <section anchor="history" numbered="true" removeInRFC="false" toc="include | |||
<name>History</name> | " pn="section-1.2"> | |||
<t>This document is based on <contact fullname="Stefan Gössner"/>'s popu | <name slugifiedName="name-history">History</name> | |||
lar JSONPath proposal | <t indent="0" pn="section-1.2-1">This document is based on <contact full | |||
dated 2007-02-21 <xref target="JSONPath-orig"/>, builds on the experience from t | name="Stefan Gössner"/>'s popular JSONPath proposal (dated 2007-02-21) <xref tar | |||
he widespread | get="JSONPath-orig" format="default" sectionFormat="of" derivedContent="JSONPath | |||
-orig"/>, builds on the experience from the widespread | ||||
deployment of its implementations, and provides a normative specification for it .</t> | deployment of its implementations, and provides a normative specification for it .</t> | |||
<t><xref target="inspired-by-xpath"/> describes how JSONPath was inspire | <t indent="0" pn="section-1.2-2"><xref target="inspired-by-xpath" format | |||
d by XML's XPath | ="default" sectionFormat="of" derivedContent="Appendix B"/> describes how JSONPa | |||
<xref target="XPath"/>.</t> | th was inspired by XML's XPath | |||
<t>JSONPath was intended as a light-weight companion to JSON | <xref target="XPath" format="default" sectionFormat="of" derivedContent="XPath"/ | |||
>.</t> | ||||
<t indent="0" pn="section-1.2-3">JSONPath was intended as a lightweight | ||||
companion to JSON | ||||
implementations in programming languages such as PHP and JavaScript, | implementations in programming languages such as PHP and JavaScript, | |||
so instead of defining its own expression language, like XPath did, | so instead of defining its own expression language, like XPath did, | |||
JSONPath delegated parts of a query to the underlying | JSONPath delegated parts of a query to the underlying | |||
runtime, e.g., JavaScript's <tt>eval()</tt> function. | runtime, e.g., JavaScript's <tt>eval()</tt> function. | |||
As JSONPath was implemented in more environments, JSONPath | As JSONPath was implemented in more environments, JSONPath | |||
expressions became decreasingly portable. | expressions became decreasingly portable. | |||
For example, regular expression processing was often delegated to a | For example, regular expression processing was often delegated to a | |||
convenient regular expression engine.</t> | convenient regular expression engine.</t> | |||
<t>This document aims to remove such implementation-specific dependencie s and | <t indent="0" pn="section-1.2-4">This document aims to remove such imple mentation-specific dependencies and | |||
serve as a common JSONPath specification that can be used across | serve as a common JSONPath specification that can be used across | |||
programming languages and environments. | programming languages and environments. | |||
This means that backwards compatibility is | This means that backwards compatibility is | |||
not always achieved; a design principle of this document is to | not always achieved; a design principle of this document is to | |||
go with a "consensus" between implementations even if it is rough, as | go with a "consensus" between implementations even if it is rough, as | |||
long as that does not jeopardize the objective of obtaining a usable, | long as that does not jeopardize the objective of obtaining a usable, | |||
stable JSON query language.</t> | stable JSON query language.</t> | |||
<t>The term <em>JSONPath</em> was chosen because of the XPath inspiratio n and also because | <t indent="0" pn="section-1.2-5">The term <em>JSONPath</em> was chosen b ecause of the XPath inspiration and also because | |||
the outcome of a query consists of <em>paths</em> identifying nodes in the | the outcome of a query consists of <em>paths</em> identifying nodes in the | |||
JSON query argument.</t> | JSON query argument.</t> | |||
</section> | </section> | |||
<section anchor="json-values"> | <section anchor="json-values" numbered="true" removeInRFC="false" toc="inc | |||
<name>JSON Values</name> | lude" pn="section-1.3"> | |||
<t>The JSON value a JSONPath query is applied to is, by definition, a | <name slugifiedName="name-json-values">JSON Values</name> | |||
<t indent="0" pn="section-1.3-1">The JSON value a JSONPath query is appl | ||||
ied to is, by definition, a | ||||
valid JSON value. A JSON value is often constructed by parsing | valid JSON value. A JSON value is often constructed by parsing | |||
a JSON text.</t> | a JSON text.</t> | |||
<t>The parsing of a JSON text into a JSON value and what happens if a JS ON | <t indent="0" pn="section-1.3-2">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. | text does not represent valid JSON are not defined by this document. | |||
Sections <xref target="RFC8259" section="4" sectionFormat="bare"/> and <xref tar get="RFC8259" section="8" sectionFormat="bare"/> of <xref target="RFC8259"/> ide ntify specific situations that may | Sections <xref target="RFC8259" section="4" sectionFormat="bare" format="default " derivedLink="https://rfc-editor.org/rfc/rfc8259#section-4" derivedContent="RFC 8259"/> and <xref target="RFC8259" section="8" sectionFormat="bare" format="defa ult" derivedLink="https://rfc-editor.org/rfc/rfc8259#section-8" derivedContent=" RFC8259"/> of <xref target="RFC8259" format="default" sectionFormat="of" derived Content="RFC8259"/> identify specific situations that may | |||
conform to the grammar for JSON texts but are not interoperable uses | conform to the grammar for JSON texts but are not interoperable uses | |||
of JSON, as they may cause unpredictable behavior. | of JSON, as they may cause unpredictable behavior. | |||
This document does not attempt to define predictable | This document does not attempt to define predictable | |||
behavior for JSONPath queries in these situations.</t> | behavior for JSONPath queries in these situations.</t> | |||
<t>Specifically, the "Semantics" subsections of Sections | <t indent="0" pn="section-1.3-3">Specifically, the "Semantics" subsectio | |||
<xref format="counter" target="name-selector"/>, <xref format="counter" target=" | ns of Sections | |||
wildcard-selector"/>, | <xref format="counter" target="name-selector" sectionFormat="of" derivedContent= | |||
<xref format="counter" target="filter-selector"/>, and <xref format="counter" ta | "2.3.1"/>, <xref format="counter" target="wildcard-selector" sectionFormat="of" | |||
rget="descendant-segment"/> describe behavior that | derivedContent="2.3.2"/>, | |||
<xref format="counter" target="filter-selector" sectionFormat="of" derivedConten | ||||
t="2.3.5"/>, and <xref format="counter" target="descendant-segment" sectionForma | ||||
t="of" derivedContent="2.5.2"/> describe behavior that | ||||
becomes unpredictable when the JSON value for one of the objects | becomes unpredictable when the JSON value for one of the objects | |||
under consideration was constructed out of JSON text that exhibits | under consideration was constructed out of JSON text that exhibits | |||
multiple members for a single object that share the same member name | multiple members for a single object that share the same member name | |||
("duplicate names", see <xref section="4" sectionFormat="of" target="RFC8259"/>) | ("duplicate names"; see <xref section="4" sectionFormat="of" target="RFC8259" fo | |||
. | rmat="default" derivedLink="https://rfc-editor.org/rfc/rfc8259#section-4" derive | |||
Also, selecting a child by name (<xref target="name-selector"/>) and comparing s | dContent="RFC8259"/>). | |||
trings | Also, when selecting a child by name (<xref target="name-selector" format="defau | |||
(<xref target="comparisons"/> in <xref target="filter-selector"/>) assume these | lt" sectionFormat="of" derivedContent="Section 2.3.1"/>) and comparing strings | |||
strings are sequences of Unicode scalar values, becoming unpredictable | (<xref target="comparisons" format="default" sectionFormat="of" derivedContent=" | |||
if they are not (<xref section="8.2" sectionFormat="of" target="RFC8259"/>).</t> | Section 2.3.5.2.2"/>), it is assumed these | |||
strings are sequences of Unicode scalar values; the behavior becomes unpredictab | ||||
le | ||||
if they are not (<xref section="8.2" sectionFormat="of" target="RFC8259" format= | ||||
"default" derivedLink="https://rfc-editor.org/rfc/rfc8259#section-8.2" derivedCo | ||||
ntent="RFC8259"/>).</t> | ||||
</section> | </section> | |||
<section anchor="overview"> | <section anchor="overview" numbered="true" removeInRFC="false" toc="includ | |||
<name>Overview of JSONPath Expressions</name> | e" pn="section-1.4"> | |||
<t>A JSONPath expression is applied to a JSON value, known as the query | <name slugifiedName="name-overview-of-jsonpath-expres">Overview of JSONP | |||
argument. | ath Expressions</name> | |||
<t indent="0" pn="section-1.4-1">A JSONPath expression is applied to a J | ||||
SON value, known as the query argument. | ||||
The output is a nodelist.</t> | The output is a nodelist.</t> | |||
<t>A JSONPath expression consists of an identifier followed by a series | <t indent="0" pn="section-1.4-2">A JSONPath expression consists of an id | |||
of zero or more segments each of which contains one or more selectors.</t> | entifier followed by a series | |||
<section anchor="ids"> | of zero or more segments, each of which contains one or more selectors.</t> | |||
<name>Identifiers</name> | <section anchor="ids" numbered="true" removeInRFC="false" toc="include" | |||
<t>The root node identifier <tt>$</tt> refers to the root node of the | pn="section-1.4.1"> | |||
query argument, | <name slugifiedName="name-identifiers">Identifiers</name> | |||
<t indent="0" pn="section-1.4.1-1">The root node identifier <tt>$</tt> | ||||
refers to the root node of the query argument, | ||||
i.e., to the argument as a whole.</t> | i.e., to the argument as a whole.</t> | |||
<t>The current node identifier <tt>@</tt> refers to the current node i | <t indent="0" pn="section-1.4.1-2">The current node identifier <tt>@</ | |||
n the context | tt> refers to the current node in the context | |||
of the evaluation of a filter expression (<xref target="filter-selector"/>).</t> | of the evaluation of a filter expression (<xref target="filter-selector" format= | |||
"default" sectionFormat="of" derivedContent="Section 2.3.5"/>).</t> | ||||
</section> | </section> | |||
<section anchor="segments"> | <section anchor="segments" numbered="true" removeInRFC="false" toc="incl | |||
<name>Segments</name> | ude" pn="section-1.4.2"> | |||
<t>Segments select children (<tt>[<selectors>]</tt>) or descenda | <name slugifiedName="name-segments">Segments</name> | |||
nts (<tt>..[<selectors>]</tt>) of an input value.</t> | <t indent="0" pn="section-1.4.2-1">Segments select children (<tt>[< | |||
<t>Segments can use <em>bracket notation</em>, for example:</t> | selectors>]</tt>) or descendants (<tt>..[<selectors>]</tt>) of an inpu | |||
<sourcecode type="JSONPath"><![CDATA[ | t value.</t> | |||
<t indent="0" pn="section-1.4.2-2">Segments can use <em>bracket notati | ||||
on</em>, for example:</t> | ||||
<sourcecode type="application/jsonpath" markers="false" pn="section-1. | ||||
4.2-3"> | ||||
$['store']['book'][0]['title'] | $['store']['book'][0]['title'] | |||
]]></sourcecode> | </sourcecode> | |||
<t>or the more compact <em>dot notation</em>, for example:</t> | <t indent="0" pn="section-1.4.2-4">or the more compact <em>dot notatio | |||
<sourcecode type="JSONPath"><![CDATA[ | n</em>, for example:</t> | |||
<sourcecode type="application/jsonpath" markers="false" pn="section-1. | ||||
4.2-5"> | ||||
$.store.book[0].title | $.store.book[0].title | |||
]]></sourcecode> | </sourcecode> | |||
<t>Bracket notation contains a comma separated list of one or more sel | <t indent="0" pn="section-1.4.2-6">Bracket notation contains one or mo | |||
ectors of any kind. | re (comma-separated) selectors of any kind. | |||
Selectors are detailed in the next section.</t> | Selectors are detailed in the next section.</t> | |||
<t>A JSONPath expression may use a combination of bracket and dot nota | <t indent="0" pn="section-1.4.2-7">A JSONPath expression may use a com | |||
tions.</t> | bination of bracket and dot notations.</t> | |||
<t>This document treats the bracket notations as canonical and defines | <t indent="0" pn="section-1.4.2-8">This document treats the bracket no | |||
the shorthand dot notation in terms | tations as canonical and defines the shorthand dot notation in terms | |||
of bracket notation. Examples and descriptions use shorthands where convenient.< | of bracket notation. Examples and descriptions use shorthand where convenient.</ | |||
/t> | t> | |||
</section> | </section> | |||
<section anchor="selectors"> | <section anchor="selectors" numbered="true" removeInRFC="false" toc="inc | |||
<name>Selectors</name> | lude" pn="section-1.4.3"> | |||
<t>A name selector, e.g. <tt>'name'</tt>, selects a named child of an | <name slugifiedName="name-selectors">Selectors</name> | |||
object.</t> | <t indent="0" pn="section-1.4.3-1">A name selector, e.g., <tt>'name'</ | |||
<t>An index selector, e.g. <tt>3</tt>, selects an indexed child of an | tt>, selects a named child of an object.</t> | |||
array.</t> | <t indent="0" pn="section-1.4.3-2">An index selector, e.g., <tt>3</tt> | |||
<t>A wildcard <tt>*</tt> (<xref target="wildcard-selector"/>) in the e | , selects an indexed child of an array.</t> | |||
xpression <tt>[*]</tt> selects all children of a | <t indent="0" pn="section-1.4.3-3">In the expression <tt>[*]</tt>, a w | |||
node and in the expression <tt>..[*]</tt> selects all descendants of a node.</t> | ildcard <tt>*</tt> (<xref target="wildcard-selector" format="default" sectionFor | |||
<t>An array slice <tt>start:end:step</tt> (<xref target="slice"/>) sel | mat="of" derivedContent="Section 2.3.2"/>) selects all children of a | |||
ects a series of | node, and in the expression <tt>..[*]</tt>, it selects all descendants of a node | |||
.</t> | ||||
<t indent="0" pn="section-1.4.3-4">An array slice <tt>start:end:step</ | ||||
tt> (<xref target="slice" format="default" sectionFormat="of" derivedContent="Se | ||||
ction 2.3.4"/>) selects a series of | ||||
elements from an array, giving a start position, an end position, and | elements from an array, giving a start position, an end position, and | |||
an optional step value that moves the position from the start to the | an optional step value that moves the position from the start to the | |||
end.</t> | end.</t> | |||
<t>Filter expressions <tt>?<logical-expr></tt> select certain ch | <t indent="0" pn="section-1.4.3-5">A filter expression <tt>?<logica | |||
ildren of an object or array, as in:</t> | l-expr></tt> selects certain children of an object or array, as in:</t> | |||
<sourcecode type="JSONPath"><![CDATA[ | <sourcecode type="application/jsonpath" markers="false" pn="section-1. | |||
$.store.book[?@.price < 10].title | 4.3-6"> | |||
]]></sourcecode> | $.store.book[?@.price < 10].title | |||
</sourcecode> | ||||
</section> | </section> | |||
<section anchor="summary"> | <section anchor="summary" numbered="true" removeInRFC="false" toc="inclu | |||
<name>Summary</name> | de" pn="section-1.4.4"> | |||
<t><xref target="tbl-overview"/> provides a brief overview of JSONPath | <name slugifiedName="name-summary">Summary</name> | |||
syntax.</t> | <t indent="0" pn="section-1.4.4-1"><xref target="tbl-overview" format= | |||
<table anchor="tbl-overview"> | "default" sectionFormat="of" derivedContent="Table 1"/> provides a brief overvie | |||
<name>Overview of JSONPath syntax</name> | w of JSONPath syntax.</t> | |||
<table anchor="tbl-overview" align="center" pn="table-1"> | ||||
<name slugifiedName="name-overview-of-jsonpath-syntax">Overview of J | ||||
SONPath Syntax</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">Syntax Element</th> | <th align="left" colspan="1" rowspan="1">Syntax Element</th> | |||
<th align="left">Description</th> | <th align="left" colspan="1" rowspan="1">Description</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$</tt></td> | <tt>$</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="root-identifier">root node identifier</xref></td | <xref target="root-identifier" format="default" sectionFormat= | |||
> | "of" derivedContent="Section 2.2">root node identifier</xref></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>@</tt></td> | <tt>@</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="filter-selector">current node identifier</xref> | <xref target="filter-selector" format="default" sectionFormat= | |||
(valid only within filter selectors)</td> | "of" derivedContent="Section 2.3.5">current node identifier</xref> (valid only w | |||
ithin filter selectors)</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[<selectors>]</tt></td> | <tt>[<selectors>]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="child-segment">child segment</xref> selects zero | <xref target="child-segment" format="default" sectionFormat="o | |||
or more children of a node; contains one or more selectors, separated by commas | f" derivedContent="Section 2.5.1">child segment</xref>: selects zero or more chi | |||
</td> | ldren of a node</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>.name</tt></td> | <tt>.name</tt></td> | |||
<td align="left">shorthand for <tt>['name']</tt></td> | <td align="left" colspan="1" rowspan="1">shorthand for <tt>['nam e']</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>.*</tt></td> | <tt>.*</tt></td> | |||
<td align="left">shorthand for <tt>[*]</tt></td> | <td align="left" colspan="1" rowspan="1">shorthand for <tt>[*]</ tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>..[<selectors>]</tt></td> | <tt>..[<selectors>]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="descendant-segment">descendant segment</xref>: s | <xref target="descendant-segment" format="default" sectionForm | |||
elects zero or more descendants of a node; contains one or more selectors, separ | at="of" derivedContent="Section 2.5.2">descendant segment</xref>: selects zero o | |||
ated by commas</td> | r more descendants of a node</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>..name</tt></td> | <tt>..name</tt></td> | |||
<td align="left">shorthand for <tt>..['name']</tt></td> | <td align="left" colspan="1" rowspan="1">shorthand for <tt>..['n ame']</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>..*</tt></td> | <tt>..*</tt></td> | |||
<td align="left">shorthand for <tt>..[*]</tt></td> | <td align="left" colspan="1" rowspan="1">shorthand for <tt>..[*] </tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>'name'</tt></td> | <tt>'name'</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="name-selector">name selector</xref>: selects a n | <xref target="name-selector" format="default" sectionFormat="o | |||
amed child of an object</td> | f" derivedContent="Section 2.3.1">name selector</xref>: selects a named child of | |||
an object</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>*</tt></td> | <tt>*</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="name-selector">wildcard selector</xref>: selects | <xref target="wildcard-selector" format="default" sectionForma | |||
all children of a node</td> | t="of" derivedContent="Section 2.3.2">wildcard selector</xref>: selects all chil | |||
dren of a node</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>3</tt></td> | <tt>3</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="index-selector">index selector</xref>: selects a | <xref target="index-selector" format="default" sectionFormat=" | |||
n indexed child of an array (from 0)</td> | of" derivedContent="Section 2.3.3">index selector</xref>: selects an indexed chi | |||
ld of an array (from 0)</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>0:100:5</tt></td> | <tt>0:100:5</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="slice">array slice selector</xref>: start:end:st | <xref target="slice" format="default" sectionFormat="of" deriv | |||
ep for arrays</td> | edContent="Section 2.3.4">array slice selector</xref>: start:end:step for arrays | |||
</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>?<logical-expr></tt></td> | <tt>?<logical-expr></tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="filter-selector">filter selector</xref>: selects | <xref target="filter-selector" format="default" sectionFormat= | |||
particular children using a logical expression</td> | "of" derivedContent="Section 2.3.5">filter selector</xref>: selects particular c | |||
hildren using a logical expression</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>length(@.foo)</tt></td> | <tt>length(@.foo)</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<xref target="fnex">function extension</xref>: invokes a funct | <xref target="fnex" format="default" sectionFormat="of" derive | |||
ion in a filter expression</td> | dContent="Section 2.4">function extension</xref>: invokes a function in a filter | |||
expression</td> | ||||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="jsonpath-examples"> | <section anchor="jsonpath-examples" numbered="true" removeInRFC="false" to | |||
<name>JSONPath Examples</name> | c="include" pn="section-1.5"> | |||
<t>This section is informative. It provides examples of JSONPath express | <name slugifiedName="name-jsonpath-examples">JSONPath Examples</name> | |||
ions.</t> | <t indent="0" pn="section-1.5-1">This section is informative. It provide | |||
<t>The examples are based on the simple JSON value shown in | s examples of JSONPath expressions.</t> | |||
<xref target="fig-example-value"/>, representing a bookstore (that also has a bi | <t indent="0" pn="section-1.5-2">The examples are based on the simple JS | |||
cycle).</t> | ON value shown in | |||
<figure anchor="fig-example-value"> | <xref target="fig-example-value" format="default" sectionFormat="of" derivedCont | |||
<name>Example JSON value</name> | ent="Figure 1"/>, representing a bookstore (which also has a bicycle).</t> | |||
<sourcecode type="json"><![CDATA[ | <figure anchor="fig-example-value" align="left" suppress-title="false" p | |||
n="figure-1"> | ||||
<name slugifiedName="name-example-json-value">Example JSON Value</name | ||||
> | ||||
<sourcecode type="json" markers="false" pn="section-1.5-3.1"> | ||||
{ "store": { | { "store": { | |||
"book": [ | "book": [ | |||
{ "category": "reference", | { "category": "reference", | |||
"author": "Nigel Rees", | "author": "Nigel Rees", | |||
"title": "Sayings of the Century", | "title": "Sayings of the Century", | |||
"price": 8.95 | "price": 8.95 | |||
}, | }, | |||
{ "category": "fiction", | { "category": "fiction", | |||
"author": "Evelyn Waugh", | "author": "Evelyn Waugh", | |||
"title": "Sword of Honour", | "title": "Sword of Honour", | |||
skipping to change at line 500 ¶ | skipping to change at line 797 ¶ | |||
"isbn": "0-395-19395-8", | "isbn": "0-395-19395-8", | |||
"price": 22.99 | "price": 22.99 | |||
} | } | |||
], | ], | |||
"bicycle": { | "bicycle": { | |||
"color": "red", | "color": "red", | |||
"price": 399 | "price": 399 | |||
} | } | |||
} | } | |||
} | } | |||
]]></sourcecode> | </sourcecode> | |||
</figure> | </figure> | |||
<t><xref target="tbl-example"/> shows some JSONPath queries that might b | <t indent="0" pn="section-1.5-4"><xref target="tbl-example" format="defa | |||
e applied to this example and their intended results.</t> | ult" sectionFormat="of" derivedContent="Table 2"/> shows some JSONPath queries t | |||
<table anchor="tbl-example"> | hat might be applied to this example and their intended results.</t> | |||
<name>Example JSONPath expressions and their intended results when app | <table anchor="tbl-example" align="center" pn="table-2"> | |||
lied to the example JSON value</name> | <name slugifiedName="name-example-jsonpath-expression">Example JSONPat | |||
h Expressions and Their Intended Results When Applied to the Example JSON Value< | ||||
/name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">JSONPath</th> | <th align="left" colspan="1" rowspan="1">JSONPath</th> | |||
<th align="left">Intended result</th> | <th align="left" colspan="1" rowspan="1">Intended Result</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$.store.book[*].author</tt></td> | <tt>$.store.book[*].author</tt></td> | |||
<td align="left">the authors of all books in the store</td> | <td align="left" colspan="1" rowspan="1">the authors of all books in the store</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..author</tt></td> | <tt>$..author</tt></td> | |||
<td align="left">all authors</td> | <td align="left" colspan="1" rowspan="1">all authors</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$.store.*</tt></td> | <tt>$.store.*</tt></td> | |||
<td align="left">all things in store, which are some books and a r ed bicycle</td> | <td align="left" colspan="1" rowspan="1">all things in the store, which are some books and a red bicycle</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$.store..price</tt></td> | <tt>$.store..price</tt></td> | |||
<td align="left">the prices of everything in the store</td> | <td align="left" colspan="1" rowspan="1">the prices of everything in the store</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[2]</tt></td> | <tt>$..book[2]</tt></td> | |||
<td align="left">the third book</td> | <td align="left" colspan="1" rowspan="1">the third book</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[2].author</tt></td> | <tt>$..book[2].author</tt></td> | |||
<td align="left">the third book's author</td> | <td align="left" colspan="1" rowspan="1">the third book's author</ td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[2].publisher</tt></td> | <tt>$..book[2].publisher</tt></td> | |||
<td align="left">empty result: the third book does not have a "pub lisher" member</td> | <td align="left" colspan="1" rowspan="1">empty result: the third b ook does not have a "publisher" member</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[-1]</tt></td> | <tt>$..book[-1]</tt></td> | |||
<td align="left">the last book in order</td> | <td align="left" colspan="1" rowspan="1">the last book in order</t d> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> | <tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> | |||
<td align="left">the first two books</td> | <td align="left" colspan="1" rowspan="1">the first two books</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[?@.isbn]</tt></td> | <tt>$..book[?@.isbn]</tt></td> | |||
<td align="left">all books with an ISBN number</td> | <td align="left" colspan="1" rowspan="1">all books with an ISBN nu mber</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[?@.price<10]</tt></td> | <tt>$..book[?@.price<10]</tt></td> | |||
<td align="left">all books cheaper than 10</td> | <td align="left" colspan="1" rowspan="1">all books cheaper than 10 </td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..*</tt></td> | <tt>$..*</tt></td> | |||
<td align="left">all member values and array elements contained in the input value</td> | <td align="left" colspan="1" rowspan="1">all member values and arr ay elements contained in the input value</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="jsonpath-syntax-and-semantics"> | <section anchor="jsonpath-syntax-and-semantics" numbered="true" removeInRFC= | |||
<name>JSONPath Syntax and Semantics</name> | "false" toc="include" pn="section-2"> | |||
<section anchor="synsem-overview"> | <name slugifiedName="name-jsonpath-syntax-and-semanti">JSONPath Syntax and | |||
<name>Overview</name> | Semantics</name> | |||
<t>A JSONPath <em>expression</em> is a string which, when applied to a J | <section anchor="synsem-overview" numbered="true" removeInRFC="false" toc= | |||
SON value, | "include" pn="section-2.1"> | |||
the <em>query argument</em>, selects zero or more nodes of the argument and outp | <name slugifiedName="name-overview">Overview</name> | |||
uts | <t indent="0" pn="section-2.1-1">A JSONPath <em>expression</em> is a str | |||
ing that, when applied to a JSON value | ||||
(the <em>query argument</em>), selects zero or more nodes of the argument and ou | ||||
tputs | ||||
these nodes as a nodelist.</t> | these nodes as a nodelist.</t> | |||
<t>A query <bcp14>MUST</bcp14> be encoded using UTF-8. | <t indent="0" pn="section-2.1-2">A query <bcp14>MUST</bcp14> be encoded using UTF-8. | |||
The grammar for queries given in this document assumes that its UTF-8 form is fi rst decoded into | The grammar for queries given in this document assumes that its UTF-8 form is fi rst decoded into | |||
Unicode scalar values as described | Unicode scalar values as described | |||
in <xref target="RFC3629"/>; implementation approaches that lead to an equivalen t | in <xref target="RFC3629" format="default" sectionFormat="of" derivedContent="RF C3629"/>; implementation approaches that lead to an equivalent | |||
result are possible.</t> | result are possible.</t> | |||
<t>A string to be used as a JSONPath query needs to be <em>well-formed</ em> and | <t indent="0" pn="section-2.1-3">A string to be used as a JSONPath query needs to be <em>well-formed</em> and | |||
<em>valid</em>. | <em>valid</em>. | |||
A string is a well-formed JSONPath query if it conforms to the ABNF syntax in th is document. | A string is a well-formed JSONPath query if it conforms to the ABNF syntax in th is document. | |||
A well-formed JSONPath query is valid if it also fulfills all semantic | A well-formed JSONPath query is valid if it also fulfills both semantic | |||
requirements posed by this document, which are:</t> | requirements posed by this document, which are as follows:</t> | |||
<ol spacing="normal" type="1"><li>Integer numbers in the JSONPath query | <ol spacing="normal" type="1" indent="adaptive" start="1" pn="section-2. | |||
that are relevant | 1-4"><li pn="section-2.1-4.1" derivedCounter="1.">Integer numbers in the JSONPat | |||
h query that are relevant | ||||
to the JSONPath processing (e.g., index values and steps) <bcp14>MUST</bcp14> be | to the JSONPath processing (e.g., index values and steps) <bcp14>MUST</bcp14> be | |||
within the range of exact integer values defined in I-JSON (see <xref section="2 | within the range of exact integer values defined in Internet JSON (I-JSON) (see | |||
.2" sectionFormat="of" target="RFC7493"/>), namely within the interval [−(2<sup> | <xref section="2.2" sectionFormat="of" target="RFC7493" format="default" derived | |||
53</sup>)+1, | Link="https://rfc-editor.org/rfc/rfc7493#section-2.2" derivedContent="RFC7493"/> | |||
(2<sup>53</sup>)−1].</li> | ), namely within the interval [-(2<sup>53</sup>)+1, | |||
<li>Uses of function extensions <bcp14>MUST</bcp14> be <em>well-typed< | (2<sup>53</sup>)-1].</li> | |||
/em>, | <li pn="section-2.1-4.2" derivedCounter="2.">Uses of function extensio | |||
as described in <xref target="fnex"/>.</li> | ns <bcp14>MUST</bcp14> be <em>well-typed</em>, | |||
as described in <xref target="well-typedness" format="default" sectionFormat="of | ||||
" derivedContent="Section 2.4.3"/>.</li> | ||||
</ol> | </ol> | |||
<t>A JSONPath implementation <bcp14>MUST</bcp14> raise an error for any query which is not | <t indent="0" pn="section-2.1-5">A JSONPath implementation <bcp14>MUST</ bcp14> raise an error for any query that is not | |||
well-formed and valid. | well-formed and valid. | |||
The well-formedness and the validity of JSONPath queries are independent of | The well-formedness and the validity of JSONPath queries are independent of | |||
the JSON value the query is applied to. No further errors relating to the | the JSON value the query is applied to. No further errors relating to the | |||
well-formedness and the validity of a JSONPath query can be | well-formedness and the validity of a JSONPath query can be | |||
raised during application of the query to a value. | raised during application of the query to a value. | |||
This clearly separates well-formedness/validity errors in the query | This clearly separates well-formedness/validity errors in the query | |||
from mismatches that may actually stem from flaws in the data.</t> | from mismatches that may actually stem from flaws in the data.</t> | |||
<t>Mismatches between the structure expected by a valid query | <t indent="0" pn="section-2.1-6">Mismatches between the structure expect ed by a valid query | |||
and the structure found in the data can lead to empty query results, | and the structure found in the data can lead to empty query results, | |||
which may be unexpected and indicate bugs in either. | which may be unexpected and indicate bugs in either. | |||
JSONPath implementations might therefore want to provide diagnostics | JSONPath implementations might therefore want to provide diagnostics | |||
to the application developer that aid in finding the cause of empty | to the application developer that aid in finding the cause of empty | |||
results.</t> | results.</t> | |||
<t>Obviously, an implementation can still fail when executing a JSONPath | <t indent="0" pn="section-2.1-7">Obviously, an implementation can still fail when executing a JSONPath | |||
query, e.g., because of resource depletion, but this is not modeled in | query, e.g., because of resource depletion, but this is not modeled in | |||
this document. However, the implementation <bcp14>MUST NOT</bcp14> | this document. However, the implementation <bcp14>MUST NOT</bcp14> | |||
silently malfunction. Specifically, if a valid JSONPath query is | silently malfunction. Specifically, if a valid JSONPath query is | |||
evaluated against a structured value whose size is too large to | evaluated against a structured value whose size is too large to | |||
process the query correctly (for instance requiring the processing of | process the query correctly (for instance, requiring the processing of | |||
numbers that fall outside the range of exact values), the implementation | numbers that fall outside the range of exact values), the implementation | |||
<bcp14>MUST</bcp14> provide an indication of overflow.</t> | <bcp14>MUST</bcp14> provide an indication of overflow.</t> | |||
<t>(Readers familiar with the HTTP error model may be reminded of 400 | <t indent="0" pn="section-2.1-8">(Readers familiar with the HTTP error m | |||
type errors when pondering well-formedness and validity, while | odel may be reminded of 400 | |||
resource depletion and related errors are comparable to 500 type | type errors when pondering well-formedness and validity, and they may | |||
recognize resource depletion and related errors as comparable to 500 type | ||||
errors.)</t> | errors.)</t> | |||
<section anchor="syntax"> | <section anchor="syntax" numbered="true" removeInRFC="false" toc="includ | |||
<name>Syntax</name> | e" pn="section-2.1.1"> | |||
<t>Syntactically, a JSONPath query consists of a root identifier (<tt> | <name slugifiedName="name-syntax">Syntax</name> | |||
$</tt>), which | <t indent="0" pn="section-2.1.1-1">Syntactically, a JSONPath query con | |||
sists of a root identifier (<tt>$</tt>), which | ||||
stands for a nodelist that contains the root node of the query argument, | stands for a nodelist that contains the root node of the query argument, | |||
followed by a possibly empty sequence of <em>segments</em>.</t> | followed by a possibly empty sequence of <em>segments</em>.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="false" pn="section-2.1.1-2"> | |||
jsonpath-query = root-identifier segments | jsonpath-query = root-identifier segments | |||
segments = *(S segment) | segments = *(S segment) | |||
B = %x20 / ; Space | B = %x20 / ; Space | |||
%x09 / ; Horizontal tab | %x09 / ; Horizontal tab | |||
%x0A / ; Line feed or New line | %x0A / ; Line feed or New line | |||
%x0D ; Carriage return | %x0D ; Carriage return | |||
S = *B ; optional blank space | S = *B ; optional blank space | |||
]]></sourcecode> | </sourcecode> | |||
<t>The syntax and semantics of segments are defined in <xref target="s | <t indent="0" pn="section-2.1.1-3">The syntax and semantics of segment | |||
egments-details"/>.</t> | s are defined in <xref target="segments-details" format="default" sectionFormat= | |||
"of" derivedContent="Section 2.5"/>.</t> | ||||
</section> | </section> | |||
<section anchor="semantics"> | <section anchor="semantics" numbered="true" removeInRFC="false" toc="inc | |||
<name>Semantics</name> | lude" pn="section-2.1.2"> | |||
<t>In this document, the semantics of a JSONPath query define the | <name slugifiedName="name-semantics">Semantics</name> | |||
<t indent="0" pn="section-2.1.2-1">In this document, the semantics of | ||||
a JSONPath query define the | ||||
required results and do not prescribe the internal workings of an | required results and do not prescribe the internal workings of an | |||
implementation. This document may describe semantics in a procedural | implementation. This document may describe semantics in a procedural | |||
step-by-step fashion, but such descriptions are normative only in the sense that | step-by-step fashion; however, such descriptions are normative only in the sense | |||
any implementation <bcp14>MUST</bcp14> produce an identical result, but not in | that any implementation <bcp14>MUST</bcp14> produce an identical result but not | |||
the sense that implementors are required to use the same algorithms.</t> | in the sense that implementers are required to use the same algorithms.</t> | |||
<t>The semantics are that a valid query is executed against a value, | <t indent="0" pn="section-2.1.2-2">The semantics are that a valid quer | |||
the <em>query argument</em>, and produces a nodelist (i.e., a list of zero or mo | y is executed against a value | |||
re nodes of the value).</t> | (the <em>query argument</em>) and produces a nodelist (i.e., a list of zero or m | |||
<t>The query is a root identifier followed by a sequence of zero or mo | ore nodes of the value).</t> | |||
re segments, each of | <t indent="0" pn="section-2.1.2-3">The query is a root identifier foll | |||
owed by a sequence of zero or more segments, each of | ||||
which is applied to the result of the previous root identifier or segment and pr ovides | which is applied to the result of the previous root identifier or segment and pr ovides | |||
input to the next segment. | input to the next segment. | |||
These results and inputs take the form of nodelists.</t> | These results and inputs take the form of nodelists.</t> | |||
<t>The nodelist resulting from the root identifier contains a single n | <t indent="0" pn="section-2.1.2-4">The nodelist resulting from the roo | |||
ode, | t identifier contains a single node | |||
the query argument. | (the query argument). | |||
The nodelist resulting from the last segment is presented as the | The nodelist resulting from the last segment is presented as the | |||
result of the query. Depending on the specific API, it might be | result of the query. Depending on the specific API, it might be | |||
presented as an array of the JSON values at the nodes, an array of | presented as an array of the JSON values at the nodes, an array of | |||
Normalized Paths referencing the nodes, or both — or some other | Normalized Paths referencing the nodes, or both -- or some other | |||
representation as desired by the implementation. | representation as desired by the implementation. | |||
Note: an empty nodelist is a valid query result.</t> | Note: An empty nodelist is a valid query result.</t> | |||
<t>A segment operates on each of the nodes in its input nodelist in tu | <t indent="0" pn="section-2.1.2-5">A segment operates on each of the n | |||
rn, | odes in its input nodelist in turn, | |||
and the resultant nodelists are concatenated in the order of the input | and the resultant nodelists are concatenated in the order of the input | |||
nodelist they were derived from to produce | nodelist they were derived from to produce | |||
the result of the segment. A node may be selected more than once and | the result of the segment. A node may be selected more than once and | |||
appears that number of times in the nodelist. Duplicate nodes are not removed.</ t> | appears that number of times in the nodelist. Duplicate nodes are not removed.</ t> | |||
<t>A syntactically valid segment <bcp14>MUST NOT</bcp14> produce error s when executing the query. | <t indent="0" pn="section-2.1.2-6">A syntactically valid segment <bcp1 4>MUST NOT</bcp14> produce errors when executing the query. | |||
This means that some | This means that some | |||
operations that might be considered erroneous, such as using an index | operations that might be considered erroneous, such as using an index | |||
lying outside the range of an array, | lying outside the range of an array, | |||
simply result in fewer nodes being selected. | simply result in fewer nodes being selected. | |||
(Additional discussion of this property can be found in the | (Additional discussion of this property can be found in the introduction of <xre | |||
introduction to <xref target="synsem-overview"/>.)</t> | f target="synsem-overview" format="default" sectionFormat="of" derivedContent="S | |||
<t>As a consequence of this approach, if any of the segments produces | ection 2.1"/>.)</t> | |||
an empty nodelist, | <t indent="0" pn="section-2.1.2-7">As a consequence of this approach, | |||
then the whole query produces an empty nodelist.</t> | if any of the segments | |||
<t>If a query may produce a nodelist with more than one possible order | produces an empty nodelist, then the whole query produces an empty | |||
ing, a particular implementation | nodelist. | |||
may also produce distinct orderings in successive runs of the query.</t> | </t> | |||
<t indent="0" pn="section-2.1.2-8">If the semantics of a query give an | ||||
implementation a choice of producing multiple possible orderings, a particular | ||||
implementation | ||||
may produce distinct orderings in successive runs of the query.</t> | ||||
</section> | </section> | |||
<section anchor="example"> | <section anchor="example" numbered="true" removeInRFC="false" toc="inclu | |||
<name>Example</name> | de" pn="section-2.1.3"> | |||
<t>Consider this example. With the query argument <tt>{"a":[{"b":0},{" | <name slugifiedName="name-example">Example</name> | |||
b":1},{"c":2}]}</tt>, the | <t indent="0" pn="section-2.1.3-1">Consider this example. With the que | |||
query <tt>$.a[*].b</tt> selects the following list of nodes: <tt>0</tt>, <tt>1</ | ry argument <tt>{"a":[{"b":0},{"b":1},{"c":2}]}</tt>, the | |||
tt> | query <tt>$.a[*].b</tt> selects the following list of nodes (denoted here by the | |||
(denoted here by their value).</t> | ir values): <tt>0</tt>, <tt>1</tt>.</t> | |||
<t>The query consists of <tt>$</tt> followed by three segments: <tt>.a | <t indent="0" pn="section-2.1.3-2">The query consists of <tt>$</tt> fo | |||
</tt>, <tt>[*]</tt>, and <tt>.b</tt>.</t> | llowed by three segments: <tt>.a</tt>, <tt>[*]</tt>, and <tt>.b</tt>.</t> | |||
<t>Firstly, <tt>$</tt> produces a nodelist consisting of just the quer | <t indent="0" pn="section-2.1.3-3">First, <tt>$</tt> produces a nodeli | |||
y argument.</t> | st consisting of just the query argument.</t> | |||
<t>Next, <tt>.a</tt> selects from any object input node and selects th | <t indent="0" pn="section-2.1.3-4">Next, <tt>.a</tt> selects from any | |||
e | object input node and selects the | |||
node of any | node of any | |||
member value of the input | member value of the input | |||
node corresponding to the member name <tt>"a"</tt>. | node corresponding to the member name <tt>"a"</tt>. | |||
The result is again a list of one node: <tt>[{"b":0},{"b":1},{"c":2}]</tt>.</t> | The result is again a list containing a single node: <tt>[{"b":0},{"b":1},{"c":2 | |||
<t>Next, <tt>[*]</tt> selects from any array input node all its elemen | }]</tt>.</t> | |||
ts | <t indent="0" pn="section-2.1.3-5">Next, <tt>[*]</tt> selects all the | |||
(for an object input node, it would select all its member | elements | |||
values, but not the member names). | from the 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> | The result is a list of three nodes: <tt>{"b":0}</tt>, <tt>{"b":1}</tt>, and <tt >{"c":2}</tt>.</t> | |||
<t>Finally, <tt>.b</tt> selects from any object input node with a memb er name | <t indent="0" pn="section-2.1.3-6">Finally, <tt>.b</tt> selects from a ny object input node with a member name | |||
<tt>b</tt> and selects the node of the member value of the input node correspond ing to that name. | <tt>b</tt> and selects the node of the member value of the input node correspond ing to that name. | |||
The result is a list containing <tt>0</tt>, <tt>1</tt>. | The result is a list containing <tt>0</tt>, <tt>1</tt>. | |||
This is the concatenation of three lists, two of length one containing | This is the concatenation of three lists: two of length one containing | |||
<tt>0</tt>, <tt>1</tt>, respectively, and one of length zero.</t> | <tt>0</tt>, <tt>1</tt>, respectively, and one of length zero.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="root-identifier"> | <section anchor="root-identifier" numbered="true" removeInRFC="false" toc= | |||
<name>Root Identifier</name> | "include" pn="section-2.2"> | |||
<section anchor="syntax-1"> | <name slugifiedName="name-root-identifier">Root Identifier</name> | |||
<name>Syntax</name> | <section anchor="syntax-1" numbered="true" removeInRFC="false" toc="incl | |||
<t>Every JSONPath query (except those inside filter expressions, see < | ude" pn="section-2.2.1"> | |||
xref target="filter-selector"/>) <bcp14>MUST</bcp14> begin with the root identif | <name slugifiedName="name-syntax-2">Syntax</name> | |||
ier <tt>$</tt>.</t> | <t indent="0" pn="section-2.2.1-1">Every JSONPath query (except those | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | inside filter expressions; see <xref target="filter-selector" format="default" s | |||
ectionFormat="of" derivedContent="Section 2.3.5"/>) <bcp14>MUST</bcp14> begin wi | ||||
th the root identifier <tt>$</tt>.</t> | ||||
<sourcecode type="abnf" name="jsonpath-collected.abnf" markers="false" | ||||
pn="section-2.2.1-2"> | ||||
root-identifier = "$" | root-identifier = "$" | |||
]]></sourcecode> | </sourcecode> | |||
</section> | </section> | |||
<section anchor="semantics-1"> | <section anchor="semantics-1" numbered="true" removeInRFC="false" toc="i | |||
<name>Semantics</name> | nclude" pn="section-2.2.2"> | |||
<t>The root identifier <tt>$</tt> represents the root node of the quer | <name slugifiedName="name-semantics-2">Semantics</name> | |||
y argument | <t indent="0" pn="section-2.2.2-1">The root identifier <tt>$</tt> repr | |||
esents the root node of the query argument | ||||
and produces a nodelist consisting of that root node.</t> | and produces a nodelist consisting of that root node.</t> | |||
</section> | </section> | |||
<section anchor="examples"> | <section anchor="examples" numbered="true" removeInRFC="false" toc="incl | |||
<name>Examples</name> | ude" pn="section-2.2.3"> | |||
<aside> | <name slugifiedName="name-examples">Examples</name> | |||
<t>In this and the following examples in Sections <xref format="coun | <aside pn="section-2.2.3-1"> | |||
ter" target="root-identifier"/> and | <t indent="0" pn="section-2.2.3-1.1">Note: In this example and the f | |||
<xref format="counter" target="selector-details"/> except for <xref target="tbl- | ollowing examples in Sections <xref format="counter" target="root-identifier" se | |||
comparison"/>, we will present a | ctionFormat="of" derivedContent="2.2"/> and | |||
<xref format="counter" target="selector-details" sectionFormat="of" derivedConte | ||||
nt="2.3"/>, except for <xref target="tbl-comparison" format="default" sectionFor | ||||
mat="of" derivedContent="Table 11"/>, we will present a | ||||
JSON text to show the JSON value used as the query argument to the | JSON text to show the JSON value used as the query argument to the | |||
queries in the examples, and then a table with the columns:</t> | queries in the examples and then a table with the following columns:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="secti | |||
<li>Query: an example query to be applied to the query argument</l | on-2.2.3-1.2"> | |||
i> | <li pn="section-2.2.3-1.2.1">Query: an example query to be applied | |||
<li>Result: the query result as a list of JSON values that were lo | to the query argument</li> | |||
cated in the query argument</li> | <li pn="section-2.2.3-1.2.2">Result: the query result as a list of | |||
<li>Result Path: the query result as a list of (normalized) paths | JSON values that were located in the query argument</li> | |||
into | <li pn="section-2.2.3-1.2.3">Result Path: the query result as a li | |||
st of (normalized) paths into | ||||
the query argument, giving locations of the JSON values in the previous column</ li> | the query argument, giving locations of the JSON values in the previous column</ li> | |||
<li>Comment: descriptive information</li> | <li pn="section-2.2.3-1.2.4">Comment: descriptive information</li> | |||
</ul> | </ul> | |||
</aside> | </aside> | |||
<t>JSON:</t> | <t indent="0" pn="section-2.2.3-2">JSON:</t> | |||
<sourcecode type="json"><![CDATA[ | <sourcecode type="json" markers="false" pn="section-2.2.3-3"> | |||
{"k": "v"} | {"k": "v"} | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.2.3-4">Queries:</t> | |||
<table anchor="tbl-root"> | <table anchor="tbl-root" align="center" pn="table-3"> | |||
<name>Root identifier examples</name> | <name slugifiedName="name-root-identifier-example">Root Identifier E | |||
xample</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Path</th> | <th align="center" colspan="1" rowspan="1">Result Path</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$</tt></td> | <tt>$</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"k": "v"}</tt></td> | <tt>{"k": "v"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$</tt></td> | <tt>$</tt></td> | |||
<td align="left">Root node</td> | <td align="left" colspan="1" rowspan="1">Root node</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="selector-details"> | <section anchor="selector-details" numbered="true" removeInRFC="false" toc | |||
<name>Selectors</name> | ="include" pn="section-2.3"> | |||
<t>Selectors appear only inside <xref target="child-segment">child segme | <name slugifiedName="name-selectors-2">Selectors</name> | |||
nts</xref> and | <t indent="0" pn="section-2.3-1">Selectors appear only inside <xref targ | |||
<xref target="descendant-segment">descendant segments</xref>.</t> | et="child-segment" format="default" sectionFormat="of" derivedContent="Section 2 | |||
<t>A selector produces a nodelist consisting of zero or more children of | .5.1">child segments</xref> and | |||
the input value.</t> | <xref target="descendant-segment" format="default" sectionFormat="of" derivedCon | |||
<t>There are various kinds of selectors which produce children of object | tent="Section 2.5.2">descendant segments</xref>.</t> | |||
s, children of arrays, | <t indent="0" pn="section-2.3-2">A selector produces a nodelist consisti | |||
ng of zero or more children of the input value.</t> | ||||
<t indent="0" pn="section-2.3-3">There are various kinds of selectors th | ||||
at produce children of objects, children of arrays, | ||||
or children of either objects or arrays.</t> | or children of either objects or arrays.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="false" p | |||
selector = name-selector / | n="section-2.3-4"> | |||
selector = name-selector / | ||||
wildcard-selector / | wildcard-selector / | |||
slice-selector / | slice-selector / | |||
index-selector / | index-selector / | |||
filter-selector | filter-selector | |||
]]></sourcecode> | </sourcecode> | |||
<t>The syntax and semantics of each kind of selector are defined below.< | <t indent="0" pn="section-2.3-5">The syntax and semantics of each kind o | |||
/t> | f selector are defined below.</t> | |||
<section anchor="name-selector"> | <section anchor="name-selector" numbered="true" removeInRFC="false" toc= | |||
<name>Name Selector</name> | "include" pn="section-2.3.1"> | |||
<section anchor="syntax-name"> | <name slugifiedName="name-name-selector">Name Selector</name> | |||
<name>Syntax</name> | <section anchor="syntax-name" numbered="true" removeInRFC="false" toc= | |||
<t>A name selector <tt>'<name>'</tt> selects at most one objec | "include" pn="section-2.3.1.1"> | |||
t member value.</t> | <name slugifiedName="name-syntax-3">Syntax</name> | |||
<t>In contrast to JSON, | <t indent="0" pn="section-2.3.1.1-1">A name selector <tt>'<name&g | |||
t;'</tt> selects at most one object member value.</t> | ||||
<t indent="0" pn="section-2.3.1.1-2">In contrast to JSON, | ||||
the JSONPath syntax allows strings to be enclosed in <em>single</em> or <em>doub le</em> quotes.</t> | the JSONPath syntax allows strings to be enclosed in <em>single</em> or <em>doub le</em> quotes.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals e" pn="section-2.3.1.1-3"> | |||
name-selector = string-literal | name-selector = string-literal | |||
string-literal = %x22 *double-quoted %x22 / ; "string" | string-literal = %x22 *double-quoted %x22 / ; "string" | |||
%x27 *single-quoted %x27 ; 'string' | %x27 *single-quoted %x27 ; 'string' | |||
double-quoted = unescaped / | double-quoted = unescaped / | |||
%x27 / ; ' | %x27 / ; ' | |||
ESC %x22 / ; \" | ESC %x22 / ; \" | |||
ESC escapable | ESC escapable | |||
single-quoted = unescaped / | single-quoted = unescaped / | |||
%x22 / ; " | %x22 / ; " | |||
ESC %x27 / ; \' | ESC %x27 / ; \' | |||
ESC escapable | ESC escapable | |||
ESC = %x5C ; \ backslash | ESC = %x5C ; \ backslash | |||
unescaped = %x20-21 / ; see RFC 8259 | unescaped = %x20-21 / ; see RFC 8259 | |||
; omit 0x22 " | ; omit 0x22 " | |||
%x23-26 / | %x23-26 / | |||
; omit 0x27 ' | ; omit 0x27 ' | |||
%x28-5B / | %x28-5B / | |||
; omit 0x5C \ | ; omit 0x5C \ | |||
%x5D-D7FF / ; skip surrogate code points | %x5D-D7FF / | |||
; skip surrogate code points | ||||
%xE000-10FFFF | %xE000-10FFFF | |||
escapable = %x62 / ; b BS backspace U+0008 | escapable = %x62 / ; b BS backspace U+0008 | |||
%x66 / ; f FF form feed U+000C | %x66 / ; f FF form feed U+000C | |||
%x6E / ; n LF line feed U+000A | %x6E / ; n LF line feed U+000A | |||
%x72 / ; r CR carriage return U+000D | %x72 / ; r CR carriage return U+000D | |||
%x74 / ; t HT horizontal tab U+0009 | %x74 / ; t HT horizontal tab U+0009 | |||
"/" / ; / slash (solidus) U+002F | "/" / ; / slash (solidus) U+002F | |||
"\" / ; \ backslash (reverse solidus) U+005C | "\" / ; \ backslash (reverse solidus) U+005C | |||
(%x75 hexchar) ; uXXXX U+XXXX | (%x75 hexchar) ; uXXXX U+XXXX | |||
hexchar = non-surrogate / | hexchar = non-surrogate / | |||
(high-surrogate "\" %x75 low-surrogate) | (high-surrogate "\" %x75 low-surrogate) | |||
non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / | non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / | |||
("D" %x30-37 2HEXDIG ) | ("D" %x30-37 2HEXDIG ) | |||
high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG | high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG | |||
low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG | low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG | |||
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | |||
]]></sourcecode> | </sourcecode> | |||
<t>Notes:</t> | <t indent="0" pn="section-2.3.1.1-4">Notes:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="secti | |||
<li> | on-2.3.1.1-5"> | |||
<tt>double-quoted</tt> strings follow the JSON string syntax (<x | <li pn="section-2.3.1.1-5.1"> | |||
ref section="7" sectionFormat="of" target="RFC8259"/>); | <tt>Double-quoted</tt> strings follow the JSON string syntax (<x | |||
<tt>single-quoted</tt> strings follow an analogous pattern (<xref target="syntax | ref section="7" sectionFormat="of" target="RFC8259" format="default" derivedLink | |||
-index"/>). | ="https://rfc-editor.org/rfc/rfc8259#section-7" derivedContent="RFC8259"/>); | |||
<tt>single-quoted</tt> strings follow an analogous pattern. | ||||
No attempt was made to improve on this syntax, so if it is desired to | No attempt was made to improve on this syntax, so if it is desired to | |||
escape characters with | escape characters with | |||
scalar values above 0xFFFF, such as <u format="num-lit-name">🤔</u>, | scalar values above 0xFFFF, such as <u format="num-lit-name" pn="u-1">🎼</u>, | |||
they need to be represented | they need to be represented | |||
by a pair of surrogate escapes (<tt>"\uD83E\uDD14"</tt> in this case).</li> | by a pair of surrogate escapes (<tt>"\uD83C\uDFBC"</tt> in this case).</li> | |||
<li>Alphabetic characters in ABNF quoted strings are case-insensit | <li pn="section-2.3.1.1-5.2">Alphabetic characters in quoted strin | |||
ive, | gs are case-insensitive in ABNF, | |||
so each of the hexadecimal digits within <tt>\u</tt> escapes (as specified in ru les | so each of the hexadecimal digits within <tt>\u</tt> escapes (as specified in ru les | |||
referenced by <tt>hexchar</tt>) can be either lower case or upper case, | referenced by <tt>hexchar</tt>) can be either lowercase or uppercase, | |||
while the <tt>u</tt> in <tt>\u</tt> needs to be lower case (indicated as <tt>%x7 | while the <tt>u</tt> in <tt>\u</tt> needs to be lowercase (indicated as <tt>%x75 | |||
5</tt>).</li> | </tt>).</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="semantics-2"> | <section anchor="semantics-2" numbered="true" removeInRFC="false" toc= | |||
<name>Semantics</name> | "include" pn="section-2.3.1.2"> | |||
<t>A <tt>name-selector</tt> string <bcp14>MUST</bcp14> be converted | <name slugifiedName="name-semantics-3">Semantics</name> | |||
to a | <t indent="0" pn="section-2.3.1.2-1">A <tt>name-selector</tt> string | |||
<bcp14>MUST</bcp14> be converted to a | ||||
member name <tt>M</tt> by removing the surrounding quotes and | member name <tt>M</tt> by removing the surrounding quotes and | |||
replacing each escape sequence with its equivalent Unicode character, as | replacing each escape sequence with its equivalent Unicode character, as | |||
shown in <xref target="tbl-esc"/>:</t> | shown in <xref target="tbl-esc" format="default" sectionFormat="of" derivedConte | |||
<table anchor="tbl-esc"> | nt="Table 4"/>:</t> | |||
<name>Escape Sequence Replacements</name> | <table anchor="tbl-esc" align="center" pn="table-4"> | |||
<name slugifiedName="name-escape-sequence-replacement">Escape Sequ | ||||
ence Replacements</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Escape Sequence</th> | <th align="center" colspan="1" rowspan="1">Escape Sequence</th | |||
<th align="center">Unicode Character</th> | > | |||
<th align="left">Description</th> | <th align="center" colspan="1" rowspan="1">Unicode Character</ | |||
th> | ||||
<th align="left" colspan="1" rowspan="1">Description</th> | ||||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\b</tt></td> | <tt>\b</tt></td> | |||
<td align="center">U+0008</td> | <td align="center" colspan="1" rowspan="1">U+0008</td> | |||
<td align="left">BS backspace</td> | <td align="left" colspan="1" rowspan="1">BS backspace</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\t</tt></td> | <tt>\t</tt></td> | |||
<td align="center">U+0009</td> | <td align="center" colspan="1" rowspan="1">U+0009</td> | |||
<td align="left">HT horizontal tab</td> | <td align="left" colspan="1" rowspan="1">HT horizontal tab</td | |||
> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\n</tt></td> | <tt>\n</tt></td> | |||
<td align="center">U+000A</td> | <td align="center" colspan="1" rowspan="1">U+000A</td> | |||
<td align="left">LF line feed</td> | <td align="left" colspan="1" rowspan="1">LF line feed</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\f</tt></td> | <tt>\f</tt></td> | |||
<td align="center">U+000C</td> | <td align="center" colspan="1" rowspan="1">U+000C</td> | |||
<td align="left">FF form feed</td> | <td align="left" colspan="1" rowspan="1">FF form feed</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\r</tt></td> | <tt>\r</tt></td> | |||
<td align="center">U+000D</td> | <td align="center" colspan="1" rowspan="1">U+000D</td> | |||
<td align="left">CR carriage return</td> | <td align="left" colspan="1" rowspan="1">CR carriage return</t | |||
d> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\"</tt></td> | <tt>\"</tt></td> | |||
<td align="center">U+0022</td> | <td align="center" colspan="1" rowspan="1">U+0022</td> | |||
<td align="left">quotation mark</td> | <td align="left" colspan="1" rowspan="1">quotation mark</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\'</tt></td> | <tt>\'</tt></td> | |||
<td align="center">U+0027</td> | <td align="center" colspan="1" rowspan="1">U+0027</td> | |||
<td align="left">apostrophe</td> | <td align="left" colspan="1" rowspan="1">apostrophe</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\/</tt></td> | <tt>\/</tt></td> | |||
<td align="center">U+002F</td> | <td align="center" colspan="1" rowspan="1">U+002F</td> | |||
<td align="left">slash (solidus)</td> | <td align="left" colspan="1" rowspan="1">slash (solidus)</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\\</tt></td> | <tt>\\</tt></td> | |||
<td align="center">U+005C</td> | <td align="center" colspan="1" rowspan="1">U+005C</td> | |||
<td align="left">backslash (reverse solidus)</td> | <td align="left" colspan="1" rowspan="1">backslash (reverse so | |||
lidus)</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>\uXXXX</tt></td> | <tt>\uXXXX</tt></td> | |||
<td align="center">see <xref target="syntax-name"/></td> | <td align="center" colspan="1" rowspan="1">see <xref target="s | |||
<td align="left">hexadecimal escape</td> | yntax-name" format="default" sectionFormat="of" derivedContent="Section 2.3.1.1" | |||
/></td> | ||||
<td align="left" colspan="1" rowspan="1">hexadecimal escape</t | ||||
d> | ||||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>Applying the <tt>name-selector</tt> to an object node | <t indent="0" pn="section-2.3.1.2-3">Applying the <tt>name-selector< | |||
selects a member value whose name equals the member name <tt>M</tt>, | /tt> to an object node | |||
selects a member value whose name equals the member name <tt>M</tt> | ||||
or selects nothing if there is no such member value. | or selects nothing if there is no such member value. | |||
Nothing is selected from a value that is not an object.</t> | Nothing is selected from a value that is not an object.</t> | |||
<t>Note: processing the name selector requires comparing the member name string <tt>M</tt> | <t indent="0" pn="section-2.3.1.2-4">Note: Processing the name selec tor requires comparing the member name string <tt>M</tt> | |||
with member name strings in the JSON to which the selector is being applied. | with member name strings in the JSON to which the selector is being applied. | |||
Two strings <bcp14>MUST</bcp14> be considered equal if and only if they are iden tical | Two strings <bcp14>MUST</bcp14> be considered equal if and only if they are iden tical | |||
sequences of Unicode scalar values. In other words, normalization operations | sequences of Unicode scalar values. In other words, normalization operations | |||
<bcp14>MUST NOT</bcp14> be applied to either the member name string <tt>M</tt> f rom the JSONPath or to | <bcp14>MUST NOT</bcp14> be applied to either the member name string <tt>M</tt> f rom the JSONPath or | |||
the member name strings in the JSON prior to comparison.</t> | the member name strings in the JSON prior to comparison.</t> | |||
</section> | </section> | |||
<section anchor="examples-1"> | <section anchor="examples-1" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.3.1.3"> | |||
<!-- EDITING NOTE: there are non-breaking spaces here between j and | <name slugifiedName="name-examples-2">Examples</name> | |||
j --> | <t indent="0" pn="section-2.3.1.3-1">JSON:</t> | |||
<!-- i.e., j j and not j j --> | <sourcecode type="json" markers="false" pn="section-2.3.1.3-2"> | |||
<t>JSON:</t> | ||||
<sourcecode type="json"><![CDATA[ | ||||
{ | { | |||
"o": {"j j": {"k.k": 3}}, | "o": {"j j": {"k.k": 3}}, | |||
"'": {"@": 2} | "'": {"@": 2} | |||
} | } | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.3.1.3-3">Queries:</t> | |||
<t>The examples in <xref target="tbl-name"/> show the name selector | <t indent="0" pn="section-2.3.1.3-4">The examples in <xref target="t | |||
in use by child segments:</t> | bl-name" format="default" sectionFormat="of" derivedContent="Table 5"/> show the | |||
<table anchor="tbl-name"> | name selector in use by child segments.</t> | |||
<name>Name selector examples</name> | <table anchor="tbl-name" align="center" pn="table-5"> | |||
<name slugifiedName="name-name-selector-examples">Name Selector Ex | ||||
amples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o['j j']</tt></td> | <tt>$.o['j j']</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"k.k": 3}</tt></td> | <tt>{"k.k": 3}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j j']</tt></td> | <tt>$['o']['j j']</tt></td> | |||
<td align="left">Named value in nested object</td> | <td align="left" colspan="1" rowspan="1">Named <br/>value in < | |||
br/>a nested <br/>object</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o['j j']['k.k']</tt></td> | <tt>$.o['j j']['k.k']</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>3</tt></td> | <tt>3</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j j']['k.k']</tt></td> | <tt>$['o']['j j']['k.k']</tt></td> | |||
<td align="left">Nesting further down</td> | <td align="left" colspan="1" rowspan="1">Nesting <br/>further | |||
<br/>down</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o["j j"]["k.k"]</tt></td> | <tt>$.o["j j"]["k.k"]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>3</tt></td> | <tt>3</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j j']['k.k']</tt></td> | <tt>$['o']['j j']['k.k']</tt></td> | |||
<td align="left">Different delimiter in query, unchanged norma | <td align="left" colspan="1" rowspan="1">Different <br/>delimi | |||
lized path</td> | ter <br/>in the query, <br/>unchanged <br/>Normalized <br/>Path</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$["'"]["@"]</tt></td> | <tt>$["'"]["@"]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>2</tt></td> | <tt>2</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['\'']['@']</tt></td> | <tt>$['\'']['@']</tt></td> | |||
<td align="left">Unusual member names</td> | <td align="left" colspan="1" rowspan="1">Unusual <br/>member < br/>names</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="wildcard-selector"> | <section anchor="wildcard-selector" numbered="true" removeInRFC="false" | |||
<name>Wildcard Selector</name> | toc="include" pn="section-2.3.2"> | |||
<section anchor="syntax-2"> | <name slugifiedName="name-wildcard-selector">Wildcard Selector</name> | |||
<name>Syntax</name> | <section anchor="syntax-2" numbered="true" removeInRFC="false" toc="in | |||
<t>The wildcard selector consists of an asterisk.</t> | clude" pn="section-2.3.2.1"> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <name slugifiedName="name-syntax-4">Syntax</name> | |||
<t indent="0" pn="section-2.3.2.1-1">The wildcard selector consists | ||||
of an asterisk.</t> | ||||
<sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | ||||
e" pn="section-2.3.2.1-2"> | ||||
wildcard-selector = "*" | wildcard-selector = "*" | |||
]]></sourcecode> | </sourcecode> | |||
</section> | </section> | |||
<section anchor="semantics-3"> | <section anchor="semantics-3" numbered="true" removeInRFC="false" toc= | |||
<name>Semantics</name> | "include" pn="section-2.3.2.2"> | |||
<t>A wildcard selector selects the nodes of all children of an objec | <name slugifiedName="name-semantics-4">Semantics</name> | |||
t or array. | <t indent="0" pn="section-2.3.2.2-1">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, | The order in which the children of an object appear in the resultant nodelist is not stipulated, | |||
since JSON objects are unordered. | since JSON objects are unordered. | |||
Children of an array appear in array order in the resultant nodelist.</t> | Children of an array appear in array order in the resultant nodelist. | |||
<t>The wildcard selector selects nothing from a primitive JSON value | </t> | |||
(that is, | <t indent="0" pn="section-2.3.2.2-2">Note that the children of an ob | |||
ject are its member values, not its member names.</t> | ||||
<t indent="0" pn="section-2.3.2.2-3">The wildcard selector selects n | ||||
othing from a primitive JSON value (that is, | ||||
a number, a string, <tt>true</tt>, <tt>false</tt>, or <tt>null</tt>).</t> | a number, a string, <tt>true</tt>, <tt>false</tt>, or <tt>null</tt>).</t> | |||
</section> | </section> | |||
<section anchor="examples-2"> | <section anchor="examples-2" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.3.2.3"> | |||
<t>JSON:</t> | <name slugifiedName="name-examples-3">Examples</name> | |||
<sourcecode type="json"><![CDATA[ | <t indent="0" pn="section-2.3.2.3-1">JSON:</t> | |||
<sourcecode type="json" markers="false" pn="section-2.3.2.3-2"> | ||||
{ | { | |||
"o": {"j": 1, "k": 2}, | "o": {"j": 1, "k": 2}, | |||
"a": [5, 3] | "a": [5, 3] | |||
} | } | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.3.2.3-3">Queries:</t> | |||
<t>The examples in <xref target="tbl-wild"/> show the wildcard selec | <t indent="0" pn="section-2.3.2.3-4">The examples in <xref target="t | |||
tor in use by a child segment:</t> | bl-wild" format="default" sectionFormat="of" derivedContent="Table 6"/> show the | |||
<table anchor="tbl-wild"> | wildcard selector in use by a child segment.</t> | |||
<name>Wildcard selector examples</name> | <table anchor="tbl-wild" align="center" pn="table-6"> | |||
<name slugifiedName="name-wildcard-selector-examples">Wildcard Sel | ||||
ector Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[*]</tt></td> | <tt>$[*]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"j": 1, "k": 2}</tt> <br/> <tt>[5, 3]</tt></td> | <tt>{"j": 1, "k": 2}</tt> <br/> <tt>[5, 3]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']</tt> <br/> <tt>$['a']</tt></td> | <tt>$['o']</tt> <br/> <tt>$['a']</tt></td> | |||
<td align="left">Object values</td> | <td align="left" colspan="1" rowspan="1">Object values</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[*]</tt></td> | <tt>$.o[*]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt> <br/> <tt>2</tt></td> | <tt>1</tt> <br/> <tt>2</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt></td> | <tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt></td> | |||
<td align="left">Object values</td> | <td align="left" colspan="1" rowspan="1">Object values</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[*]</tt></td> | <tt>$.o[*]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>2</tt> <br/> <tt>1</tt></td> | <tt>2</tt> <br/> <tt>1</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> | <tt>$['o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> | |||
<td align="left">Alternative result</td> | <td align="left" colspan="1" rowspan="1">Alternative result</t d> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[*, *]</tt></td> | <tt>$.o[*, *]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt ></td> | <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt ></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$[ 'o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> | <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> | <td align="left" colspan="1" rowspan="1">Non-deterministic ord ering</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[*]</tt></td> | <tt>$.a[*]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>5</tt> <br/> <tt>3</tt></td> | <tt>5</tt> <br/> <tt>3</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt></td> | <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt></td> | |||
<td align="left">Array members</td> | <td align="left" colspan="1" rowspan="1">Array members</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>The example above with the query <tt>$.o[*, *]</tt> shows that th | <t indent="0" pn="section-2.3.2.3-6">The example above with the quer | |||
e wildcard selector may produce nodelists in distinct | y <tt>$.o[*, *]</tt> shows that the wildcard selector may produce nodelists in d | |||
orders each time it appears in the child segment, when it is applied to an objec | istinct | |||
t node with two or more | orders each time it appears in the child segment when it is applied to an object | |||
node with two or more | ||||
members (but not when it is applied to object nodes with fewer than two members or to array nodes).</t> | members (but not when it is applied to object nodes with fewer than two members or to array nodes).</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="index-selector"> | <section anchor="index-selector" numbered="true" removeInRFC="false" toc | |||
<name>Index Selector</name> | ="include" pn="section-2.3.3"> | |||
<section anchor="syntax-index"> | <name slugifiedName="name-index-selector">Index Selector</name> | |||
<name>Syntax</name> | <section anchor="syntax-index" numbered="true" removeInRFC="false" toc | |||
<t>An index selector <tt><index></tt> matches at most one arra | ="include" pn="section-2.3.3.1"> | |||
y element value.</t> | <name slugifiedName="name-syntax-5">Syntax</name> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <t indent="0" pn="section-2.3.3.1-1">An index selector <tt><index | |||
></tt> matches at most one array element value.</t> | ||||
<sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | ||||
e" pn="section-2.3.3.1-2"> | ||||
index-selector = int ; decimal integer | index-selector = int ; decimal integer | |||
int = "0" / | int = "0" / | |||
(["-"] DIGIT1 *DIGIT) ; - optional | (["-"] DIGIT1 *DIGIT) ; - optional | |||
DIGIT1 = %x31-39 ; 1-9 non-zero digit | DIGIT1 = %x31-39 ; 1-9 non-zero digit | |||
]]></sourcecode> | </sourcecode> | |||
<t>Applying the numerical <tt>index-selector</tt> selects the corres | <t indent="0" pn="section-2.3.3.1-3">Applying the numerical <tt>inde | |||
ponding | x-selector</tt> selects the corresponding | |||
element. JSONPath allows it to be negative (see <xref target="index-semantics"/> | element. JSONPath allows it to be negative (see <xref target="index-semantics" f | |||
).</t> | ormat="default" sectionFormat="of" derivedContent="Section 2.3.3.2"/>).</t> | |||
<t>To be valid, the index selector value <bcp14>MUST</bcp14> be in t | <t indent="0" pn="section-2.3.3.1-4">To be valid, the index selector | |||
he I-JSON | value <bcp14>MUST</bcp14> be in the I-JSON | |||
range of exact values, see <xref target="synsem-overview"/>.</t> | range of exact values (see <xref target="synsem-overview" format="default" secti | |||
<t>Notes:</t> | onFormat="of" derivedContent="Section 2.1"/>).</t> | |||
<ul spacing="normal"> | <t indent="0" pn="section-2.3.3.1-5">Notes:</t> | |||
<li>An <tt>index-selector</tt> is an integer (in base 10, as in JS | <ul spacing="normal" bare="false" empty="false" indent="3" pn="secti | |||
ON numbers).</li> | on-2.3.3.1-6"> | |||
<li>As in JSON numbers, the syntax does not allow octal-like integ | <li pn="section-2.3.3.1-6.1">An <tt>index-selector</tt> is an inte | |||
ers with leading zeros such as <tt>01</tt> or <tt>-01</tt>.</li> | ger (in base 10, as in JSON numbers).</li> | |||
<li pn="section-2.3.3.1-6.2">As in JSON numbers, the syntax does n | ||||
ot allow octal-like integers with leading zeros, such as <tt>01</tt> or <tt>-01< | ||||
/tt>.</li> | ||||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="index-semantics"> | <section anchor="index-semantics" numbered="true" removeInRFC="false" | |||
<name>Semantics</name> | toc="include" pn="section-2.3.3.2"> | |||
<t>A non-negative <tt>index-selector</tt> applied to an array select | <name slugifiedName="name-semantics-5">Semantics</name> | |||
s an array element using a zero-based index. | <t indent="0" pn="section-2.3.3.2-1">A non-negative <tt>index-select | |||
For example, the selector <tt>0</tt> selects the first and the selector <tt>4</t | or</tt> applied to an array selects an array element using a zero-based index. | |||
t> selects the fifth element of a sufficiently long array. | For example, the selector <tt>0</tt> selects the first, and the selector <tt>4</ | |||
tt> selects the fifth element of a sufficiently long array. | ||||
Nothing is selected, and it is not an error, if the index lies outside the range of the array. Nothing is selected from a value that is not an array.</t> | Nothing is selected, and it is not an error, if the index lies outside the range of the array. Nothing is selected from a value that is not an array.</t> | |||
<t>A negative <tt>index-selector</tt> counts from the array end back | <t indent="0" pn="section-2.3.3.2-2">A negative <tt>index-selector</ | |||
wards, | tt> counts from the array end backwards, | |||
obtaining an equivalent non-negative <tt>index-selector</tt> by summing the | obtaining an equivalent non-negative <tt>index-selector</tt> by adding the | |||
length of the array with the negative index. | length of the array to the negative index. | |||
For example, the selector <tt>-1</tt> selects the last and the selector <tt>-2</ | For example, the selector <tt>-1</tt> selects the last, and the selector <tt>-2< | |||
tt> selects the penultimate element of an array with at least two elements. | /tt> selects the penultimate element of an array with at least two elements. | |||
As with non-negative indexes, it is not an error if such an element does | As with non-negative indexes, it is not an error if such an element does | |||
not exist; this simply means that no element is selected.</t> | not exist; this simply means that no element is selected.</t> | |||
</section> | </section> | |||
<section anchor="examples-3"> | <section anchor="examples-3" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.3.3.3"> | |||
<!-- EDITING NOTE: there are non-breaking spaces here between j and | <name slugifiedName="name-examples-4">Examples</name> | |||
j --> | <t indent="0" pn="section-2.3.3.3-1">JSON:</t> | |||
<!-- i.e., j j and not j j --> | <sourcecode type="json" markers="false" pn="section-2.3.3.3-2"> | |||
<t>JSON:</t> | ||||
<sourcecode type="json"><![CDATA[ | ||||
["a","b"] | ["a","b"] | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.3.3.3-3">Queries:</t> | |||
<t>The examples in <xref target="tbl-index"/> show the index selecto | <t indent="0" pn="section-2.3.3.3-4">The examples in <xref target="t | |||
r in use by a child segment.</t> | bl-index" format="default" sectionFormat="of" derivedContent="Table 7"/> show th | |||
<table anchor="tbl-index"> | e index selector in use by a child segment.</t> | |||
<name>Index selector examples</name> | <table anchor="tbl-index" align="center" pn="table-7"> | |||
<name slugifiedName="name-index-selector-examples">Index Selector | ||||
Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1]</tt></td> | <tt>$[1]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"b"</tt></td> | <tt>"b"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1]</tt></td> | <tt>$[1]</tt></td> | |||
<td align="left">Element of array</td> | <td align="left" colspan="1" rowspan="1">Element of array</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[-2]</tt></td> | <tt>$[-2]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"a"</tt></td> | <tt>"a"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0]</tt></td> | <tt>$[0]</tt></td> | |||
<td align="left">Element of array, from the end</td> | <td align="left" colspan="1" rowspan="1">Element of array, fro m the end</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="slice"> | <section anchor="slice" numbered="true" removeInRFC="false" toc="include | |||
<name>Array Slice selector</name> | " pn="section-2.3.4"> | |||
<section anchor="syntax-3"> | <name slugifiedName="name-array-slice-selector">Array Slice Selector</ | |||
<name>Syntax</name> | name> | |||
<t>The array slice selector has the form <tt><start>:<end&g | <section anchor="syntax-3" numbered="true" removeInRFC="false" toc="in | |||
t;:<step></tt>. | clude" pn="section-2.3.4.1"> | |||
It matches elements from arrays starting at index <tt><start></tt>, ending | <name slugifiedName="name-syntax-6">Syntax</name> | |||
at — but | <t indent="0" pn="section-2.3.4.1-1">The array slice selector has th | |||
not including — <tt><end></tt>, while incrementing by <tt>step</tt> with a | e form <tt><start>:<end>:<step></tt>. | |||
default of <tt>1</tt>.</t> | It matches elements from arrays starting at index <tt><start></tt> and end | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | ing at (but | |||
not 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" markers="fals | ||||
e" pn="section-2.3.4.1-2"> | ||||
slice-selector = [start S] ":" S [end S] [":" [S step ]] | slice-selector = [start S] ":" S [end S] [":" [S step ]] | |||
start = int ; included in selection | start = int ; included in selection | |||
end = int ; not included in selection | end = int ; not included in selection | |||
step = int ; default: 1 | step = int ; default: 1 | |||
]]></sourcecode> | </sourcecode> | |||
<t>The slice selector consists of three optional decimal integers se | <t indent="0" pn="section-2.3.4.1-3">The slice selector consists of | |||
parated by colons. | three optional decimal integers separated by colons. | |||
The second colon can be omitted when the third integer is.</t> | The second colon can be omitted when the third integer is omitted.</t> | |||
<t>To be valid, the integers provided <bcp14>MUST</bcp14> be in the | <t indent="0" pn="section-2.3.4.1-4">To be valid, the integers provi | |||
I-JSON | ded <bcp14>MUST</bcp14> be in the I-JSON | |||
range of exact values, see <xref target="synsem-overview"/>.</t> | range of exact values (see <xref target="synsem-overview" format="default" secti | |||
onFormat="of" derivedContent="Section 2.1"/>).</t> | ||||
</section> | </section> | |||
<section anchor="semantics-4"> | <section anchor="semantics-4" numbered="true" removeInRFC="false" toc= | |||
<name>Semantics</name> | "include" pn="section-2.3.4.2"> | |||
<t>The slice selector was inspired by the slice operator of ECMAScri | <name slugifiedName="name-semantics-6">Semantics</name> | |||
pt | <t indent="0" pn="section-2.3.4.2-1">The slice selector was inspired | |||
4 (ES4), which was deprecated in 2014, and that of Python.</t> | by | |||
<section anchor="informal-introduction"> | the slice operator that was proposed for ECMAScript 4 (ES4), whic | |||
<name>Informal Introduction</name> | h was never released, | |||
<t>This section is informative.</t> | and that of Python.</t> | |||
<t>Array slicing is inspired by the behavior of the <tt>Array.prot | <section anchor="informal-introduction" numbered="true" removeInRFC= | |||
otype.slice</tt> method | "false" toc="exclude" pn="section-2.3.4.2.1"> | |||
of the JavaScript language as defined by the ECMA-262 standard <xref target="ECM | <name slugifiedName="name-informal-introduction">Informal Introduc | |||
A-262"/>, | tion</name> | |||
<t indent="0" pn="section-2.3.4.2.1-1">This section is informative | ||||
.</t> | ||||
<t indent="0" pn="section-2.3.4.2.1-2">Array slicing is inspired b | ||||
y the behavior of the <tt>Array.prototype.slice</tt> method | ||||
of the JavaScript language, as defined by the ECMA-262 standard <xref target="EC | ||||
MA-262" format="default" sectionFormat="of" derivedContent="ECMA-262"/>, | ||||
with the addition of the <tt>step</tt> parameter, which is inspired by the Pytho n slice expression.</t> | with the addition of the <tt>step</tt> parameter, which is inspired by the Pytho n slice expression.</t> | |||
<t>The array slice expression <tt>start:end:step</tt> selects elem ents at indices starting at <tt>start</tt>, | <t indent="0" pn="section-2.3.4.2.1-3">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 exc luded). | incrementing by <tt>step</tt>, and ending with <tt>end</tt> (which is itself exc luded). | |||
So, for example, the expression <tt>1:3</tt> (where <tt>step</tt> defaults to <t t>1</tt>) | So, for example, the expression <tt>1:3</tt> (where <tt>step</tt> defaults to <t t>1</tt>) | |||
selects elements with indices <tt>1</tt> and <tt>2</tt> (in that order) whereas | selects elements with indices <tt>1</tt> and <tt>2</tt> (in that order), whereas | |||
<tt>1:5:2</tt> selects elements with indices <tt>1</tt> and <tt>3</tt>.</t> | <tt>1:5:2</tt> selects elements with indices <tt>1</tt> and <tt>3</tt>.</t> | |||
<t>When <tt>step</tt> is negative, elements are selected in revers | <t indent="0" pn="section-2.3.4.2.1-4">When <tt>step</tt> is negat | |||
e order. Thus, | ive, elements are selected in reverse order. Thus, | |||
for example, <tt>5:1:-2</tt> selects elements with indices <tt>5</tt> and <tt>3< | for example, <tt>5:1:-2</tt> selects elements with indices <tt>5</tt> and <tt>3< | |||
/tt>, in | /tt> (in | |||
that order and <tt>::-1</tt> selects all the elements of an array in | that order), and <tt>::-1</tt> selects all the elements of an array in | |||
reverse order.</t> | reverse order.</t> | |||
<t>When <tt>step</tt> is <tt>0</tt>, no elements are selected. | <t indent="0" pn="section-2.3.4.2.1-5">When <tt>step</tt> is <tt>0 </tt>, no elements are selected. | |||
(This is the one case that differs from the behavior of Python, which | (This is the one case that differs from the behavior of Python, which | |||
raises an error in this case.)</t> | raises an error in this case.)</t> | |||
<t>The following section specifies the behavior fully, without dep ending on | <t indent="0" pn="section-2.3.4.2.1-6">The following section speci fies the behavior fully, without depending on | |||
JavaScript or Python behavior.</t> | JavaScript or Python behavior.</t> | |||
</section> | </section> | |||
<section anchor="normative-semantics"> | <section anchor="normative-semantics" numbered="true" removeInRFC="f | |||
<name>Normative Semantics</name> | alse" toc="exclude" pn="section-2.3.4.2.2"> | |||
<t>A slice expression selects a subset of the elements of the inpu | <name slugifiedName="name-normative-semantics">Normative Semantics | |||
t array, in | </name> | |||
<t indent="0" pn="section-2.3.4.2.2-1">A slice expression selects | ||||
a subset of the elements of the input array in | ||||
the same order | the same order | |||
as the array or the reverse order, depending on the sign of the <tt>step</tt> pa rameter. | as the array or the reverse order, depending on the sign of the <tt>step</tt> pa rameter. | |||
It selects no nodes from a node that is not an array.</t> | It selects no nodes from a node that is not an array.</t> | |||
<t>A slice is defined by the two slice parameters, <tt>start</tt> and <tt>end</tt>, and | <t indent="0" pn="section-2.3.4.2.2-2">A slice is defined by the t wo slice parameters, <tt>start</tt> and <tt>end</tt>, and | |||
an iteration delta, <tt>step</tt>. | an iteration delta, <tt>step</tt>. | |||
Each of these parameters is | Each of these parameters is | |||
optional. In the rest of this section, <tt>len</tt> denotes the length of the in put array.</t> | optional. In the rest of this section, <tt>len</tt> denotes the length of the in put array.</t> | |||
<t>The default value for <tt>step</tt> is <tt>1</tt>. | <t indent="0" pn="section-2.3.4.2.2-3">The default value for <tt>s tep</tt> is <tt>1</tt>. | |||
The default values for <tt>start</tt> and <tt>end</tt> depend on the sign of <tt >step</tt>, | The default values for <tt>start</tt> and <tt>end</tt> depend on the sign of <tt >step</tt>, | |||
as shown in <xref target="tbl-slice-start-end"/>:</t> | as shown in <xref target="tbl-slice-start-end" format="default" sectionFormat="o | |||
<table anchor="tbl-slice-start-end"> | f" derivedContent="Table 8"/>.</t> | |||
<name>Default array slice start and end values</name> | <table anchor="tbl-slice-start-end" align="center" pn="table-8"> | |||
<name slugifiedName="name-default-array-slice-start-a">Default A | ||||
rray Slice start and end Values</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">Condition</th> | <th align="left" colspan="1" rowspan="1">Condition</th> | |||
<th align="left">start</th> | <th align="left" colspan="1" rowspan="1">start</th> | |||
<th align="left">end</th> | <th align="left" colspan="1" rowspan="1">end</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left">step >= 0</td> | <td align="left" colspan="1" rowspan="1">step >= 0</td> | |||
<td align="left">0</td> | <td align="left" colspan="1" rowspan="1">0</td> | |||
<td align="left">len</td> | <td align="left" colspan="1" rowspan="1">len</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">step < 0</td> | <td align="left" colspan="1" rowspan="1">step < 0</td> | |||
<td align="left">len - 1</td> | <td align="left" colspan="1" rowspan="1">len - 1</td> | |||
<td align="left">-len - 1</td> | <td align="left" colspan="1" rowspan="1">-len - 1</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>Slice expression parameters <tt>start</tt> and <tt>end</tt> are not directly usable | <t indent="0" pn="section-2.3.4.2.2-5">Slice expression parameters <tt>start</tt> and <tt>end</tt> are not directly usable | |||
as slice bounds and must first be normalized. | as slice bounds and must first be normalized. | |||
Normalization for this purpose is defined as:</t> | Normalization for this purpose is defined as:</t> | |||
<sourcecode type="pseudocode"><![CDATA[ | <sourcecode type="pseudocode" markers="false" pn="section-2.3.4.2. 2-6"> | |||
FUNCTION Normalize(i, len): | FUNCTION Normalize(i, len): | |||
IF i >= 0 THEN | IF i >= 0 THEN | |||
RETURN i | RETURN i | |||
ELSE | ELSE | |||
RETURN len + i | RETURN len + i | |||
END IF | END IF | |||
]]></sourcecode> | </sourcecode> | |||
<t>The result of the array index expression <tt>i</tt> applied to | <t indent="0" pn="section-2.3.4.2.2-7">The result of the array ind | |||
an array | ex expression <tt>i</tt> applied to an array | |||
of length <tt>len</tt> is the result of the 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> | 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>. | <t indent="0" pn="section-2.3.4.2.2-8">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 | The direction of the iteration, defined | |||
by the sign of <tt>step</tt>, determines which of the parameters is the lower bo und and which | by the sign of <tt>step</tt>, determines which of the parameters is the lower bo und and which | |||
is the upper bound:</t> | is the upper bound:</t> | |||
<sourcecode type="pseudocode"><![CDATA[ | <sourcecode type="pseudocode" markers="false" pn="section-2.3.4.2. 2-9"> | |||
FUNCTION Bounds(start, end, step, len): | FUNCTION Bounds(start, end, step, len): | |||
n_start = Normalize(start, len) | n_start = Normalize(start, len) | |||
n_end = Normalize(end, len) | n_end = Normalize(end, len) | |||
IF step >= 0 THEN | IF step >= 0 THEN | |||
lower = MIN(MAX(n_start, 0), len) | lower = MIN(MAX(n_start, 0), len) | |||
upper = MIN(MAX(n_end, 0), len) | upper = MIN(MAX(n_end, 0), len) | |||
ELSE | ELSE | |||
upper = MIN(MAX(n_start, -1), len-1) | upper = MIN(MAX(n_start, -1), len-1) | |||
lower = MIN(MAX(n_end, -1), len-1) | lower = MIN(MAX(n_end, -1), len-1) | |||
END IF | END IF | |||
RETURN (lower, upper) | RETURN (lower, upper) | |||
]]></sourcecode> | </sourcecode> | |||
<t>The slice expression selects elements with indices between the | <t indent="0" pn="section-2.3.4.2.2-10">The slice expression selec | |||
lower and | ts elements with indices between the lower and | |||
upper bounds. | upper bounds. | |||
In the following pseudocode, <tt>a(i)</tt> is the <tt>i+1</tt>th element of the array <tt>a</tt> | 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 fort h).</t> | (i.e., <tt>a(0)</tt> is the first element, <tt>a(1)</tt> the second, and so fort h).</t> | |||
<sourcecode type="pseudocode"><![CDATA[ | <sourcecode type="pseudocode" markers="false" pn="section-2.3.4.2. | |||
IF step > 0 THEN | 2-11"> | |||
IF step > 0 THEN | ||||
i = lower | i = lower | |||
WHILE i < upper: | WHILE i < upper: | |||
SELECT a(i) | SELECT a(i) | |||
i = i + step | i = i + step | |||
END WHILE | END WHILE | |||
ELSE if step < 0 THEN | ELSE if step < 0 THEN | |||
i = upper | i = upper | |||
WHILE lower < i: | WHILE lower < i: | |||
SELECT a(i) | SELECT a(i) | |||
i = i + step | i = i + step | |||
END WHILE | END WHILE | |||
END IF | END IF | |||
]]></sourcecode> | </sourcecode> | |||
<t>When <tt>step = 0</tt>, no elements are selected and the result | <t indent="0" pn="section-2.3.4.2.2-12">When <tt>step = 0</tt>, no | |||
array is empty.</t> | elements are selected, and the result array is empty.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="examples-4"> | <section anchor="examples-4" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.3.4.3"> | |||
<t>JSON:</t> | <name slugifiedName="name-examples-5">Examples</name> | |||
<sourcecode type="json"><![CDATA[ | <t indent="0" pn="section-2.3.4.3-1">JSON:</t> | |||
<sourcecode type="json" markers="false" pn="section-2.3.4.3-2"> | ||||
["a", "b", "c", "d", "e", "f", "g"] | ["a", "b", "c", "d", "e", "f", "g"] | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.3.4.3-3">Queries:</t> | |||
<t>The examples in <xref target="tbl-slice"/> show the array slice s | <t indent="0" pn="section-2.3.4.3-4">The examples in <xref target="t | |||
elector in use by a child segment:</t> | bl-slice" format="default" sectionFormat="of" derivedContent="Table 9"/> show th | |||
<table anchor="tbl-slice"> | e array slice selector in use by a child segment.</t> | |||
<name>Array slice selector examples</name> | <table anchor="tbl-slice" align="center" pn="table-9"> | |||
<name slugifiedName="name-array-slice-selector-exampl">Array Slice | ||||
Selector Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1:3]</tt></td> | <tt>$[1:3]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"b"</tt> <br/> <tt>"c"</tt></td> | <tt>"b"</tt> <br/> <tt>"c"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1]</tt> <br/> <tt>$[2]</tt></td> | <tt>$[1]</tt> <br/> <tt>$[2]</tt></td> | |||
<td align="left">Slice with default step</td> | <td align="left" colspan="1" rowspan="1">Slice with default st ep</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[5:]</tt></td> | <tt>$[5:]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"f"</tt> <br/> <tt>"g"</tt></td> | <tt>"f"</tt> <br/> <tt>"g"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[5]</tt> <br/> <tt>$[6]</tt></td> | <tt>$[5]</tt> <br/> <tt>$[6]</tt></td> | |||
<td align="left">Slice with no end index</td> | <td align="left" colspan="1" rowspan="1">Slice with no end ind ex</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1:5:2]</tt></td> | <tt>$[1:5:2]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"b"</tt> <br/> <tt>"d"</tt></td> | <tt>"b"</tt> <br/> <tt>"d"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1]</tt> <br/> <tt>$[3]</tt></td> | <tt>$[1]</tt> <br/> <tt>$[3]</tt></td> | |||
<td align="left">Slice with step 2</td> | <td align="left" colspan="1" rowspan="1">Slice with step 2</td > | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[5:1:-2]</tt></td> | <tt>$[5:1:-2]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"f"</tt> <br/> <tt>"d"</tt></td> | <tt>"f"</tt> <br/> <tt>"d"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[5]</tt> <br/> <tt>$[3]</tt></td> | <tt>$[5]</tt> <br/> <tt>$[3]</tt></td> | |||
<td align="left">Slice with negative step</td> | <td align="left" colspan="1" rowspan="1">Slice with negative s tep</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[::-1]</tt></td> | <tt>$[::-1]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"g"</tt> <br/> <tt>"f"</tt> <br/> <tt>"e"</tt> <br/> <tt >"d"</tt> <br/> <tt>"c"</tt> <br/> <tt>"b"</tt> <br/> <tt>"a"</tt></td> | <tt>"g"</tt> <br/> <tt>"f"</tt> <br/> <tt>"e"</tt> <br/> <tt >"d"</tt> <br/> <tt>"c"</tt> <br/> <tt>"b"</tt> <br/> <tt>"a"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[6]</tt> <br/> <tt>$[5]</tt> <br/> <tt>$[4]</tt> <br/> <tt>$[3]</tt> <br/> <tt>$[2]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[0]</tt></td> | <tt>$[6]</tt> <br/> <tt>$[5]</tt> <br/> <tt>$[4]</tt> <br/> <tt>$[3]</tt> <br/> <tt>$[2]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[0]</tt></td> | |||
<td align="left">Slice in reverse order</td> | <td align="left" colspan="1" rowspan="1">Slice in reverse orde r</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="filter-selector"> | <section anchor="filter-selector" numbered="true" removeInRFC="false" to | |||
<name>Filter selector</name> | c="include" pn="section-2.3.5"> | |||
<t>Filter selectors are used to iterate over the elements or members o | <name slugifiedName="name-filter-selector">Filter Selector</name> | |||
f | <t indent="0" pn="section-2.3.5-1">Filter selectors are used to iterat | |||
e over the elements or members of | ||||
structured values, i.e., JSON arrays and objects. | structured values, i.e., JSON arrays and objects. | |||
The structured values are identified in the nodelist offered by the | The structured values are identified in the nodelist offered by the | |||
child or descendant segment using the filter selector.</t> | child or descendant segment using the filter selector.</t> | |||
<t>For each iteration (element/member), a logical expression, the <em> | <t indent="0" pn="section-2.3.5-2">For each iteration (element/member) | |||
filter expression</em>, | , a logical expression (the <em>filter expression</em>) | |||
is evaluated which decides whether the node of | is evaluated, which decides whether the node of | |||
the element/member is selected. | the element/member is selected. | |||
(While a logical expression evaluates to what mathematically is a | (While a logical expression evaluates to what mathematically is a | |||
Boolean value, this specification uses the term <em>logical</em> to maintain a d istinction from | Boolean value, this specification uses the term <em>logical</em> to maintain a d istinction from | |||
the Boolean values that JSON can represent.)</t> | the Boolean values that JSON can represent.)</t> | |||
<t>During the iteration process, the filter expression receives the no de | <t indent="0" pn="section-2.3.5-3">During the iteration process, the f ilter expression receives the node | |||
of each array element or object member value of the structured value being | of each array element or object member value of the structured value being | |||
filtered; this element or member value is then known as the <em>current node</em >.</t> | filtered; this element or member value is then known as the <em>current node</em >.</t> | |||
<t>The current node can be used as the start of one or more JSONPath | <t indent="0" pn="section-2.3.5-4">The current node can be used as the start of one or more JSONPath | |||
queries in subexpressions of the filter expression, notated | queries in subexpressions of the filter expression, notated | |||
via the current-node-identifier <tt>@</tt>. | via the current-node-identifier <tt>@</tt>. | |||
Each JSONPath query can be used either for testing existence of a | Each JSONPath query can be used either for testing existence of a | |||
result of the query, for obtaining a specific JSON value resulting | result of the query, for obtaining a specific JSON value resulting | |||
from that query that can then be used in a comparison, or as a | from that query that can then be used in a comparison, or as a | |||
<em>function argument</em>.</t> | <em>function argument</em>.</t> | |||
<t>Filter selectors may use function extensions, which are covered in <xref target="fnex"/>. | <t indent="0" pn="section-2.3.5-5">Filter selectors may use function e xtensions, which are covered in <xref target="fnex" format="default" sectionForm at="of" derivedContent="Section 2.4"/>. | |||
Within the logical expression for a filter selector, function | Within the logical expression for a filter selector, function | |||
expressions can be used to operate on nodelists and values. | expressions can be used to operate on nodelists and values. | |||
The set of available functions is extensible, with a number of | The set of available functions is extensible, with a number of | |||
functions predefined, see <xref target="fnex"/>, and the ability to register fur | functions predefined (see <xref target="fnex" format="default" sectionFormat="of | |||
ther | " derivedContent="Section 2.4"/>) and the ability to register further | |||
functions provided by the Function Extensions sub-registry (<xref target="iana-f | functions provided by the "Function Extensions" subregistry (<xref target="iana- | |||
nex"/>). | fnex" format="default" sectionFormat="of" derivedContent="Section 3.2"/>). | |||
When a function is defined, it is given a unique name, and its return value and | When a function is defined, it is given a unique name, and its return value and | |||
each of its parameters is given a | each of its parameters are given a | |||
<em>declared type</em>. | <em>declared type</em>. | |||
The type system is limited in scope; its purpose is to express | The type system is limited in scope; its purpose is to express | |||
restrictions that, without functions, are implicit in the grammar of | restrictions that, without functions, are implicit in the grammar of | |||
filter expressions. | filter expressions. | |||
The type system also guides conversions (<xref target="type-conv"/>) that mimic the | The type system also guides conversions (<xref target="type-conv" format="defaul t" sectionFormat="of" derivedContent="Section 2.4.2"/>) that mimic the | |||
way different kinds of expressions are handled in the grammar when | way different kinds of expressions are handled in the grammar when | |||
function expressions are not in use.</t> | function expressions are not in use.</t> | |||
<section anchor="filter-selector-syntax"> | <section anchor="filter-selector-syntax" numbered="true" removeInRFC=" | |||
<name>Syntax</name> | false" toc="include" pn="section-2.3.5.1"> | |||
<t>The filter selector has the form <tt>?<logical-expr></tt>.< | <name slugifiedName="name-syntax-7">Syntax</name> | |||
/t> | <t indent="0" pn="section-2.3.5.1-1">The filter selector has the for | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | m <tt>?<logical-expr></tt>.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | ||||
e" pn="section-2.3.5.1-2"> | ||||
filter-selector = "?" S logical-expr | filter-selector = "?" S logical-expr | |||
]]></sourcecode> | </sourcecode> | |||
<t>As the filter expression is composed of side-effect free constitu | <t indent="0" pn="section-2.3.5.1-3">As the filter expression is com | |||
ents, | posed of constituents free of side effects, | |||
the order of evaluation does not need to be (and is not) defined. | the order of evaluation does not need to be (and is not) defined. | |||
Similarly, for conjunction (<tt>&&</tt>) and disjunction (<tt>||</tt>) ( defined later), | Similarly, for conjunction (<tt>&&</tt>) and disjunction (<tt>||</tt>) ( defined later), | |||
both a short-circuiting and a fully evaluating | both a short-circuiting and a fully evaluating | |||
implementation will lead to the same result; both implementation | implementation will lead to the same result; both implementation | |||
strategies are therefore valid.</t> | strategies are therefore valid.</t> | |||
<t>The current node is accessible via the current node identifier <t t>@</tt>. | <t indent="0" pn="section-2.3.5.1-4">The current node is accessible via the current node identifier <tt>@</tt>. | |||
This identifier addresses the current node of the filter-selector that | This identifier addresses the current node of the filter-selector that | |||
is directly enclosing the identifier. Note: within nested | is directly enclosing the identifier. Note: Within nested | |||
filter-selectors, there is no syntax to address the current node of | filter-selectors, there is no syntax to address the current node of | |||
any other than the directly enclosing filter-selector (i.e., of | any other than the directly enclosing filter-selector (i.e., of | |||
filter-selectors enclosing the filter-selector that is directly | filter-selectors enclosing the filter-selector that is directly | |||
enclosing the identifier).</t> | enclosing the identifier).</t> | |||
<t>Logical expressions offer the usual Boolean operators (<tt>||</tt > for OR, | <t indent="0" pn="section-2.3.5.1-5">Logical expressions offer the u sual Boolean operators (<tt>||</tt> for OR, | |||
<tt>&&</tt> for AND, and <tt>!</tt> for NOT). | <tt>&&</tt> for AND, and <tt>!</tt> for NOT). | |||
They have the normal semantics of Boolean algebra and obey its laws | They have the normal semantics of Boolean algebra and obey its laws | |||
(see, for example, <xref target="BOOLEAN-LAWS"/>). | (for example, see <xref target="BOOLEAN-LAWS" format="default" sectionFormat="of " derivedContent="BOOLEAN-LAWS"/>). | |||
Parentheses <bcp14>MAY</bcp14> be used within <tt>logical-expr</tt> for grouping .</t> | Parentheses <bcp14>MAY</bcp14> be used within <tt>logical-expr</tt> for grouping .</t> | |||
<t>It is not required that <tt>logical-expr</tt> consist of | <t indent="0" pn="section-2.3.5.1-6">It is not required that <tt>log | |||
a parenthesized expression (which was required in <xref target="JSONPath-orig"/> | ical-expr</tt> consist of | |||
), | a parenthesized expression (which was required in <xref target="JSONPath-orig" f | |||
ormat="default" sectionFormat="of" derivedContent="JSONPath-orig"/>), | ||||
although it can be, and the semantics are the same | although it can be, and the semantics are the same | |||
as without the parentheses.</t> | as without the parentheses.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals e" pn="section-2.3.5.1-7"> | |||
logical-expr = logical-or-expr | logical-expr = logical-or-expr | |||
logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) | logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) | |||
; disjunction | ; disjunction | |||
; binds less tightly than conjunction | ; binds less tightly than conjunction | |||
logical-and-expr = basic-expr *(S "&&" S basic-expr) | logical-and-expr = basic-expr *(S "&&" S basic-expr) | |||
; conjunction | ; conjunction | |||
; binds more tightly than disjunction | ; binds more tightly than disjunction | |||
basic-expr = paren-expr / | basic-expr = paren-expr / | |||
comparison-expr / | comparison-expr / | |||
test-expr | test-expr | |||
paren-expr = [logical-not-op S] "(" S logical-expr S ")" | paren-expr = [logical-not-op S] "(" S logical-expr S ")" | |||
; parenthesized expression | ; parenthesized expression | |||
logical-not-op = "!" ; logical NOT operator | logical-not-op = "!" ; logical NOT operator | |||
]]></sourcecode> | </sourcecode> | |||
<t>A test expression | <t indent="0" pn="section-2.3.5.1-8">A test expression | |||
either tests the existence of a node | either tests the existence of a node | |||
designated by an embedded query (see <xref target="extest"/>) or tests the | designated by an embedded query (see <xref target="extest" format="default" sect | |||
result of a function expression (see <xref target="fnex"/>). | ionFormat="of" derivedContent="Section 2.3.5.2.1"/>) or tests the | |||
result of a function expression (see <xref target="fnex" format="default" sectio | ||||
nFormat="of" derivedContent="Section 2.4"/>). | ||||
In the latter case, if the function's declared result type is | In the latter case, if the function's declared result type is | |||
<tt>LogicalType</tt> (see <xref target="typesys"/>), it tests whether the result | <tt>LogicalType</tt> (see <xref target="typesys" format="default" sectionFormat= "of" derivedContent="Section 2.4.1"/>), it tests whether the result | |||
is <tt>LogicalTrue</tt>; if the function's declared result type is | is <tt>LogicalTrue</tt>; if the function's declared result type is | |||
<tt>NodesType</tt>, it tests whether the result is non-empty. | <tt>NodesType</tt>, it tests whether the result is non-empty. | |||
If the function's declared result type is <tt>ValueType</tt>, its use in a | If the function's declared result type is <tt>ValueType</tt>, its use in a | |||
test expression is not well-typed (see <xref target="well-typedness"/>).</t> | test expression is not well-typed (see <xref target="well-typedness" format="def | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | ault" sectionFormat="of" derivedContent="Section 2.4.3"/>).</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | ||||
e" pn="section-2.3.5.1-9"> | ||||
test-expr = [logical-not-op S] | test-expr = [logical-not-op S] | |||
(filter-query / ; existence/non-existence | (filter-query / ; existence/non-existence | |||
function-expr) ; LogicalType or NodesType | function-expr) ; LogicalType or NodesType | |||
filter-query = rel-query / jsonpath-query | filter-query = rel-query / jsonpath-query | |||
rel-query = current-node-identifier segments | rel-query = current-node-identifier segments | |||
current-node-identifier = "@" | current-node-identifier = "@" | |||
]]></sourcecode> | </sourcecode> | |||
<t>Comparison expressions are available for comparisons between prim | <t indent="0" pn="section-2.3.5.1-10">Comparison expressions are ava | |||
itive | ilable for comparisons between primitive | |||
values (that is, numbers, strings, <tt>true</tt>, <tt>false</tt>, and <tt>null</ tt>). | values (that is, numbers, strings, <tt>true</tt>, <tt>false</tt>, and <tt>null</ tt>). | |||
These can be obtained via literal values; singular queries, each of | These can be obtained via literal values; singular queries, each of | |||
which selects at most one node the value of which is then used; or | which selects at most one node, the value of which is then used; or | |||
function expressions (see <xref target="fnex"/>) of type <tt>ValueType</tt>.</t> | function expressions (see <xref target="fnex" format="default" sectionFormat="of | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | " derivedContent="Section 2.4"/>) of type <tt>ValueType</tt>.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | ||||
e" pn="section-2.3.5.1-11"> | ||||
comparison-expr = comparable S comparison-op S comparable | comparison-expr = comparable S comparison-op S comparable | |||
literal = number / string-literal / | literal = number / string-literal / | |||
true / false / null | true / false / null | |||
comparable = literal / | comparable = literal / | |||
singular-query / ; singular query value | singular-query / ; singular query value | |||
function-expr ; ValueType | function-expr ; ValueType | |||
comparison-op = "==" / "!=" / | comparison-op = "==" / "!=" / | |||
"<=" / ">=" / | "<=" / ">=" / | |||
"<" / ">" | "<" / ">" | |||
singular-query = rel-singular-query / abs-singular-query | singular-query = rel-singular-query / abs-singular-query | |||
rel-singular-query = current-node-identifier singular-query-segments | rel-singular-query = current-node-identifier singular-query-segments | |||
abs-singular-query = root-identifier singular-query-segments | abs-singular-query = root-identifier singular-query-segments | |||
singular-query-segments = *(S (name-segment / index-segment)) | singular-query-segments = *(S (name-segment / index-segment)) | |||
name-segment = ("[" name-selector "]") / | name-segment = ("[" name-selector "]") / | |||
("." member-name-shorthand) | ("." member-name-shorthand) | |||
index-segment = "[" index-selector "]" | index-segment = "[" index-selector "]" | |||
]]></sourcecode> | </sourcecode> | |||
<t>Literals can be notated in the way that is usual for JSON (with t | <t indent="0" pn="section-2.3.5.1-12">Literals can be notated in the | |||
he | way that is usual for JSON (with the | |||
extension that strings can use single-quote delimiters).</t> | extension that strings can use single-quote delimiters).</t> | |||
<t>Note: Alphabetic characters in ABNF quoted strings are case-insen | <t indent="0" pn="section-2.3.5.1-13">Note: Alphabetic characters in | |||
sitive, so within a | quoted strings are case-insensitive in ABNF, so within a | |||
floating point number the ABNF expression "e" can be either the character | floating point number, the ABNF expression "e" can be either the character | |||
'e' or 'E'.</t> | 'e' or 'E'.</t> | |||
<t><tt>true</tt>, <tt>false</tt>, and <tt>null</tt> are lower-case o | <t indent="0" pn="section-2.3.5.1-14"><tt>true</tt>, <tt>false</tt>, | |||
nly (case-sensitive).</t> | and <tt>null</tt> are lowercase only (case-sensitive).</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | |||
e" pn="section-2.3.5.1-15"> | ||||
number = (int / "-0") [ frac ] [ exp ] ; decimal number | number = (int / "-0") [ frac ] [ exp ] ; decimal number | |||
frac = "." 1*DIGIT ; decimal fraction | frac = "." 1*DIGIT ; decimal fraction | |||
exp = "e" [ "-" / "+" ] 1*DIGIT ; decimal exponent | exp = "e" [ "-" / "+" ] 1*DIGIT ; decimal exponent | |||
true = %x74.72.75.65 ; true | true = %x74.72.75.65 ; true | |||
false = %x66.61.6c.73.65 ; false | false = %x66.61.6c.73.65 ; false | |||
null = %x6e.75.6c.6c ; null | null = %x6e.75.6c.6c ; null | |||
]]></sourcecode> | </sourcecode> | |||
<t><xref target="tbl-prec"/> lists filter expression operators in or | <t indent="0" pn="section-2.3.5.1-16"><xref target="tbl-prec" format | |||
der of precedence from highest (binds most tightly) to lowest (binds least tight | ="default" sectionFormat="of" derivedContent="Table 10"/> lists filter expressio | |||
ly).</t> | n operators in order of precedence from highest (binds most tightly) to lowest ( | |||
<!-- FIXME: Should the syntax column be split between unary and bina | binds least tightly).</t> | |||
ry operators? --> | <table anchor="tbl-prec" align="center" pn="table-10"> | |||
<name slugifiedName="name-filter-expression-operator-">Filter Expr | ||||
<table anchor="tbl-prec"> | ession Operator Precedence</name> | |||
<name>Filter expression operator precedence</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Precedence</th> | <th align="center" colspan="1" rowspan="1">Precedence</th> | |||
<th align="center">Operator type</th> | <th align="center" colspan="1" rowspan="1">Operator type</th> | |||
<th align="center">Syntax</th> | <th align="center" colspan="1" rowspan="1">Syntax</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center">5</td> | <td align="center" colspan="1" rowspan="1">5</td> | |||
<td align="center">Grouping <br/> Function Expressions</td> | <td align="center" colspan="1" rowspan="1">Grouping <br/> Func | |||
<td align="center"> | tion Expressions</td> | |||
<td align="center" colspan="1" rowspan="1"> | ||||
<tt>(...)</tt> <br/> <em>name</em><tt>(...)</tt></td> | <tt>(...)</tt> <br/> <em>name</em><tt>(...)</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center">4</td> | <td align="center" colspan="1" rowspan="1">4</td> | |||
<td align="center">Logical NOT</td> | <td align="center" colspan="1" rowspan="1">Logical NOT</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>!</tt></td> | <tt>!</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center">3</td> | <td align="center" colspan="1" rowspan="1">3</td> | |||
<td align="center">Relations</td> | <td align="center" colspan="1" rowspan="1">Relations</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>==</tt> <tt>!=</tt><br/><tt><</tt> <tt><=</tt> <tt | <tt>==</tt> <tt>!=</tt><br/><tt><</tt> <tt><=</tt> <tt | |||
>></tt> <tt>>=</tt></td> | >></tt> <tt>>=</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center">2</td> | <td align="center" colspan="1" rowspan="1">2</td> | |||
<td align="center">Logical AND</td> | <td align="center" colspan="1" rowspan="1">Logical AND</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>&&</tt></td> | <tt>&&</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center">1</td> | <td align="center" colspan="1" rowspan="1">1</td> | |||
<td align="center">Logical OR</td> | <td align="center" colspan="1" rowspan="1">Logical OR</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>||</tt></td> | <tt>||</tt></td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
<section anchor="semantics-5"> | <section anchor="semantics-5" numbered="true" removeInRFC="false" toc= | |||
<name>Semantics</name> | "include" pn="section-2.3.5.2"> | |||
<t>The filter selector works with arrays and objects exclusively. It | <name slugifiedName="name-semantics-7">Semantics</name> | |||
s result is a list of <em>zero</em>, <em>one</em>, <em>multiple</em> or <em>all< | <t indent="0" pn="section-2.3.5.2-1">The filter selector works with | |||
/em> of their array elements or member values, respectively. | arrays and objects exclusively. Its result is a list of (<em>zero</em>, <em>one< | |||
/em>, <em>multiple</em>, or <em>all</em>) their array elements or member values, | ||||
respectively. | ||||
Applied to a primitive value, it selects nothing (and therefore does | Applied to a primitive value, it selects nothing (and therefore does | |||
not contribute to the result of the filter selector).</t> | not contribute to the result of the filter selector).</t> | |||
<t>In the resultant nodelist, children of an array are ordered by th eir position in the array. | <t indent="0" pn="section-2.3.5.2-2">In the resultant nodelist, chil dren 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) | The order in which the children of an object (as opposed to an array) | |||
appear in the resultant nodelist is not stipulated, | appear in the resultant nodelist is not stipulated, | |||
since JSON objects are unordered.</t> | since JSON objects are unordered.</t> | |||
<section anchor="extest"> | <section anchor="extest" numbered="true" removeInRFC="false" toc="ex | |||
<name>Existence Tests</name> | clude" pn="section-2.3.5.2.1"> | |||
<t>A query by itself in a logical context is an existence test whi | <name slugifiedName="name-existence-tests">Existence Tests</name> | |||
ch yields true if the query selects at least one node and yields false if the qu | <t indent="0" pn="section-2.3.5.2.1-1">A query by itself in a logi | |||
ery does not select any nodes.</t> | cal context is an existence test that yields true if the query selects at least | |||
<t>Existence tests differ from comparisons in that:</t> | one node and yields false if the query does not select any nodes.</t> | |||
<ul spacing="normal"> | <t indent="0" pn="section-2.3.5.2.1-2">Existence tests differ from | |||
<li>they work with arbitrary relative or absolute queries (not j | comparisons in that:</t> | |||
ust singular queries).</li> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="sec | |||
<li>they work with queries that select structured values.</li> | tion-2.3.5.2.1-3"> | |||
<li pn="section-2.3.5.2.1-3.1">They work with arbitrary relative | ||||
or absolute queries (not just singular queries).</li> | ||||
<li pn="section-2.3.5.2.1-3.2">They work with queries that selec | ||||
t structured values.</li> | ||||
</ul> | </ul> | |||
<t>To examine the value of a node selected by a query, an explicit | <t indent="0" pn="section-2.3.5.2.1-4">To examine the value of a n | |||
comparison is necessary. | ode selected by a query, an explicit comparison is necessary. | |||
For example, to test whether the node selected by the query <tt>@.foo</tt> has t | For example, to test whether the node selected by the query <tt>@.foo</tt> has t | |||
he value <tt>null</tt>, use <tt>@.foo == null</tt> (see <xref target="null-seman | he value <tt>null</tt>, use <tt>@.foo == null</tt> (see <xref target="null-seman | |||
tics"/>) | tics" format="default" sectionFormat="of" derivedContent="Section 2.6"/>) | |||
rather than the negated existence test <tt>!@.foo</tt> (which yields false if <t t>@.foo</tt> selects a node, regardless of the node's value). | rather than the negated existence test <tt>!@.foo</tt> (which yields false if <t t>@.foo</tt> selects a node, regardless of the node's value). | |||
Similarly, <tt>@.foo == false</tt> yields true only if <tt>@.foo</tt> selects a node and | Similarly, <tt>@.foo == false</tt> yields true only if <tt>@.foo</tt> selects a node and | |||
the value of that node is <tt>false</tt>.</t> | the value of that node is <tt>false</tt>.</t> | |||
</section> | </section> | |||
<section anchor="comparisons"> | <section anchor="comparisons" numbered="true" removeInRFC="false" to | |||
<name>Comparisons</name> | c="exclude" pn="section-2.3.5.2.2"> | |||
<t>The comparison operators <tt>==</tt> and <tt><</tt> are defi | <name slugifiedName="name-comparisons">Comparisons</name> | |||
ned first and then these are used to define <tt>!=</tt>, <tt><=</tt>, <tt>> | <t indent="0" pn="section-2.3.5.2.2-1">The comparison operators <t | |||
;</tt>, and <tt>>=</tt>.</t> | t>==</tt> and <tt><</tt> are defined first, and then these are used to define | |||
<t>When either side of a comparison results in an empty nodelist o | <tt>!=</tt>, <tt><=</tt>, <tt>></tt>, and <tt>>=</tt>.</t> | |||
r the | <t indent="0" pn="section-2.3.5.2.2-2">When either side of a compa | |||
special result <tt>Nothing</tt> (see <xref target="typesys"/>):</t> | rison results in an empty nodelist or the | |||
<ul spacing="normal"> | special result <tt>Nothing</tt> (see <xref target="typesys" format="default" sec | |||
<li>a comparison using the operator <tt>==</tt> yields true if a | tionFormat="of" derivedContent="Section 2.4.1"/>):</t> | |||
nd only the | <ul spacing="normal" bare="false" empty="false" indent="3" pn="sec | |||
tion-2.3.5.2.2-3"> | ||||
<li pn="section-2.3.5.2.2-3.1">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> | other side also results in an empty nodelist or the special result <tt>Nothing</ tt>.</li> | |||
<li>a comparison using the operator <tt><</tt> yields false.< /li> | <li pn="section-2.3.5.2.2-3.2">A comparison using the operator < tt><</tt> yields false.</li> | |||
</ul> | </ul> | |||
<t>When any query or function expression on either side of a compa rison results in a nodelist consisting of a single node, that side is | <t indent="0" pn="section-2.3.5.2.2-4">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> | replaced by the value of its node and then:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="sec | |||
<li> | tion-2.3.5.2.2-5"> | |||
<t>a comparison using the operator <tt>==</tt> yields true if | <li pn="section-2.3.5.2.2-5.1"> | |||
and only if the comparison | <t indent="0" pn="section-2.3.5.2.2-5.1.1">A comparison using | |||
the operator <tt>==</tt> yields true if and only if the comparison | ||||
is between: | is between: | |||
</t> | </t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn= | |||
<li>numbers expected to interoperate as per <xref section="2 | "section-2.3.5.2.2-5.1.2"> | |||
.2" sectionFormat="of" target="RFC7493">I-JSON</xref> that compare equal using n | <li pn="section-2.3.5.2.2-5.1.2.1">numbers expected to inter | |||
ormal mathematical equality,</li> | operate, as per <xref section="2.2" sectionFormat="of" target="RFC7493" format=" | |||
<li>numbers at least one of which is not expected to interop | default" derivedLink="https://rfc-editor.org/rfc/rfc7493#section-2.2" derivedCon | |||
erate as per I-JSON, where the numbers compare equal using an implementation spe | tent="RFC7493">I-JSON</xref>, that compare equal using normal mathematical equal | |||
cific equality,</li> | ity,</li> | |||
<li>equal primitive values which are not numbers,</li> | <li pn="section-2.3.5.2.2-5.1.2.2">numbers, at least one of | |||
<li>equal arrays, that is arrays of the same length where ea | which is not expected to interoperate as per I-JSON, where the numbers compare e | |||
ch element of the first array is equal to the corresponding | qual using an implementation-specific equality,</li> | |||
<li pn="section-2.3.5.2.2-5.1.2.3">equal primitive values th | ||||
at are not numbers,</li> | ||||
<li pn="section-2.3.5.2.2-5.1.2.4">equal arrays, that is, ar | ||||
rays of the same length where each element of the first array is equal to the co | ||||
rresponding | ||||
element of the second array, or</li> | element of the second array, or</li> | |||
<li> | <li pn="section-2.3.5.2.2-5.1.2.5"> | |||
<t>equal objects with no duplicate names, that is where: | <t indent="0" pn="section-2.3.5.2.2-5.1.2.5.1">equal objec | |||
ts with no duplicate names, that is, where: | ||||
</t> | </t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" | |||
<li>both objects have the same collection of names (with | pn="section-2.3.5.2.2-5.1.2.5.2"> | |||
no duplicates), and</li> | <li pn="section-2.3.5.2.2-5.1.2.5.2.1">both objects have | |||
<li>for each of those names, the values associated with | the same collection of names (with no duplicates) and</li> | |||
the name by the objects are equal.</li> | <li pn="section-2.3.5.2.2-5.1.2.5.2.2">for each of those | |||
names, the values associated with the name by the objects are equal.</li> | ||||
</ul> | </ul> | |||
</li> | </li> | |||
</ul> | </ul> | |||
</li> | </li> | |||
<li> | <li pn="section-2.3.5.2.2-5.2"> | |||
<t>a comparison using the operator <tt><</tt> yields true i | <t indent="0" pn="section-2.3.5.2.2-5.2.1">A comparison using | |||
f and only if | the operator <tt><</tt> yields true if and only if | |||
the comparison is between values which are both numbers or both strings and whic | the comparison is between values that are both numbers or both strings and that | |||
h satisfy the comparison: </t> | satisfy the comparison: </t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn= | |||
<li>numbers expected to interoperate as per <xref section="2 | "section-2.3.5.2.2-5.2.2"> | |||
.2" sectionFormat="of" target="RFC7493">I-JSON</xref> <bcp14>MUST</bcp14> compar | <li pn="section-2.3.5.2.2-5.2.2.1">numbers expected to inter | |||
e using the normal mathematical ordering; | operate, as per <xref section="2.2" sectionFormat="of" target="RFC7493" format=" | |||
numbers not expected to interoperate as per I-JSON <bcp14>MAY</bcp14> compare us | default" derivedLink="https://rfc-editor.org/rfc/rfc7493#section-2.2" derivedCon | |||
ing an implementation specific ordering</li> | tent="RFC7493">I-JSON</xref>, <bcp14>MUST</bcp14> compare using the normal mathe | |||
<li>the empty string compares less than any non-empty string | matical ordering; | |||
</li> | numbers not expected to interoperate, as per I-JSON, <bcp14>MAY</bcp14> compare | |||
<li>a non-empty string compares less than another non-empty | using an implementation-specific ordering,</li> | |||
string if and only if the first string starts with a | <li pn="section-2.3.5.2.2-5.2.2.2">the empty string compares | |||
less than any non-empty string, and</li> | ||||
<li pn="section-2.3.5.2.2-5.2.2.3">a non-empty string compar | ||||
es less than another non-empty string if and only if the first string starts wit | ||||
h a | ||||
lower Unicode scalar value than the second string or if both strings start with the same Unicode scalar value and | lower Unicode scalar value than the second string or if both strings start with the same Unicode scalar value and | |||
the remainder of the first string compares less than the remainder of the second string.</li> | the remainder of the first string compares less than the remainder of the second string.</li> | |||
</ul> | </ul> | |||
</li> | </li> | |||
</ul> | </ul> | |||
<t><tt>!=</tt>, <tt><=</tt>, <tt>></tt>, and <tt>>=</tt> | <t indent="0" pn="section-2.3.5.2.2-6"><tt>!=</tt>, <tt><=</tt> | |||
are defined in terms of the other comparison operators. For any <tt>a</tt> and < | , <tt>></tt>, and <tt>>=</tt> are defined in terms of the other comparison | |||
tt>b</tt>:</t> | operators. For any <tt>a</tt> and <tt>b</tt>:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="sec | |||
<li>The comparison <tt>a != b</tt> yields true if and only if <t | tion-2.3.5.2.2-7"> | |||
t>a == b</tt> yields false.</li> | <li pn="section-2.3.5.2.2-7.1">The comparison <tt>a != b</tt> yi | |||
<li>The comparison <tt>a <= b</tt> yields true if and only if | elds true if and only if <tt>a == b</tt> yields false.</li> | |||
<tt>a < b</tt> yields true or <tt>a == b</tt> yields true.</li> | <li pn="section-2.3.5.2.2-7.2">The comparison <tt>a <= b</tt> | |||
<li>The comparison <tt>a > b</tt> yields true if and only if | yields true if and only if <tt>a < b</tt> yields true or <tt>a == b</tt> yie | |||
<tt>b < a</tt> yields true.</li> | lds true.</li> | |||
<li>The comparison <tt>a >= b</tt> yields true if and only if | <li pn="section-2.3.5.2.2-7.3">The comparison <tt>a > b</tt> | |||
<tt>b < a</tt> yields true or <tt>a == b</tt> yields true.</li> | yields true if and only if <tt>b < a</tt> yields true.</li> | |||
<li pn="section-2.3.5.2.2-7.4">The comparison <tt>a >= b</tt> | ||||
yields true if and only if <tt>b < a</tt> yields true or <tt>a == b</tt> yie | ||||
lds true.</li> | ||||
</ul> | </ul> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="examples-5"> | <section anchor="examples-5" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.3.5.3"> | |||
<t>The first set of examples shows some comparison expressions and t | <name slugifiedName="name-examples-6">Examples</name> | |||
heir | <t indent="0" pn="section-2.3.5.3-1">The first set of examples shows | |||
some comparison expressions and their | ||||
result with a given JSON value as input.</t> | result with a given JSON value as input.</t> | |||
<t>JSON:</t> | <t indent="0" pn="section-2.3.5.3-2">JSON:</t> | |||
<sourcecode type="json"><![CDATA[ | <sourcecode type="json" markers="false" pn="section-2.3.5.3-3"> | |||
{ | { | |||
"obj": {"x": "y"}, | "obj": {"x": "y"}, | |||
"arr": [2, 3] | "arr": [2, 3] | |||
} | } | |||
]]></sourcecode> | </sourcecode> | |||
<t>Comparisons:</t> | <t indent="0" pn="section-2.3.5.3-4">Comparisons:</t> | |||
<table anchor="tbl-comparison"> | <table anchor="tbl-comparison" align="center" pn="table-11"> | |||
<name>Comparison examples</name> | <name slugifiedName="name-comparison-examples">Comparison Examples | |||
</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Comparison</th> | <th align="center" colspan="1" rowspan="1">Comparison</th> | |||
<th align="center">Result</th> | <th align="center" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Comment</th> | <th align="center" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.absent1 == $.absent2</tt></td> | <tt>$.absent1 == $.absent2</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Empty nodelists</td> | <td align="center" colspan="1" rowspan="1">Empty nodelists</td | |||
> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.absent1 <= $.absent2</tt></td> | <tt>$.absent1 <= $.absent2</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>==</tt> implies <tt><=</tt></td> | <tt>==</tt> implies <tt><=</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.absent == 'g'</tt></td> | <tt>$.absent == 'g'</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Empty nodelist</td> | <td align="center" colspan="1" rowspan="1">Empty nodelist</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.absent1 != $.absent2</tt></td> | <tt>$.absent1 != $.absent2</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Empty nodelists</td> | <td align="center" colspan="1" rowspan="1">Empty nodelists</td | |||
> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.absent != 'g'</tt></td> | <tt>$.absent != 'g'</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Empty nodelist</td> | <td align="center" colspan="1" rowspan="1">Empty nodelist</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>1 <= 2</tt></td> | <tt>1 <= 2</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Numeric comparison</td> | <td align="center" colspan="1" rowspan="1">Numeric comparison< | |||
/td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>1 > 2</tt></td> | <tt>1 > 2</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Strict, numeric comparison</td> | <td align="center" colspan="1" rowspan="1">Numeric comparison< | |||
/td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>13 == '13'</tt></td> | <tt>13 == '13'</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Type mismatch</td> | <td align="center" colspan="1" rowspan="1">Type mismatch</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>'a' <= 'b'</tt></td> | <tt>'a' <= 'b'</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">String comparison</td> | <td align="center" colspan="1" rowspan="1">String comparison</ | |||
td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>'a' > 'b'</tt></td> | <tt>'a' > 'b'</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Strict, string comparison</td> | <td align="center" colspan="1" rowspan="1">String comparison</ | |||
td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj == $.arr</tt></td> | <tt>$.obj == $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Type mismatch</td> | <td align="center" colspan="1" rowspan="1">Type mismatch</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj != $.arr</tt></td> | <tt>$.obj != $.arr</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Type mismatch</td> | <td align="center" colspan="1" rowspan="1">Type mismatch</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj == $.obj</tt></td> | <tt>$.obj == $.obj</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Object comparison</td> | <td align="center" colspan="1" rowspan="1">Object comparison</ | |||
td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj != $.obj</tt></td> | <tt>$.obj != $.obj</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Object comparison</td> | <td align="center" colspan="1" rowspan="1">Object comparison</ | |||
td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.arr == $.arr</tt></td> | <tt>$.arr == $.arr</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Array comparison</td> | <td align="center" colspan="1" rowspan="1">Array comparison</t | |||
d> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.arr != $.arr</tt></td> | <tt>$.arr != $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Array comparison</td> | <td align="center" colspan="1" rowspan="1">Array comparison</t | |||
d> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj == 17</tt></td> | <tt>$.obj == 17</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Type mismatch</td> | <td align="center" colspan="1" rowspan="1">Type mismatch</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj != 17</tt></td> | <tt>$.obj != 17</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center">Type mismatch</td> | <td align="center" colspan="1" rowspan="1">Type mismatch</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj <= $.arr</tt></td> | <tt>$.obj <= $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Objects and arrays do not offer <tt><</t | <td align="center" colspan="1" rowspan="1">Objects and arrays | |||
t> comparison</td> | do not offer <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj < $.arr</tt></td> | <tt>$.obj < $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Objects and arrays do not offer <tt><</t | <td align="center" colspan="1" rowspan="1">Objects and arrays | |||
t> comparison</td> | do not offer <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.obj <= $.obj</tt></td> | <tt>$.obj <= $.obj</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>==</tt> implies <tt><=</tt></td> | <tt>==</tt> implies <tt><=</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.arr <= $.arr</tt></td> | <tt>$.arr <= $.arr</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>==</tt> implies <tt><=</tt></td> | <tt>==</tt> implies <tt><=</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>1 <= $.arr</tt></td> | <tt>1 <= $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Arrays do not offer <tt><</tt> compariso | <td align="center" colspan="1" rowspan="1">Arrays do not offer | |||
n</td> | <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>1 >= $.arr</tt></td> | <tt>1 >= $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Arrays do not offer <tt><</tt> compariso | <td align="center" colspan="1" rowspan="1">Arrays do not offer | |||
n</td> | <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>1 > $.arr</tt></td> | <tt>1 > $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Arrays do not offer <tt><</tt> compariso | <td align="center" colspan="1" rowspan="1">Arrays do not offer | |||
n</td> | <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>1 < $.arr</tt></td> | <tt>1 < $.arr</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Arrays do not offer <tt><</tt> compariso | <td align="center" colspan="1" rowspan="1">Arrays do not offer | |||
n</td> | <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>true <= true</tt></td> | <tt>true <= true</tt></td> | |||
<td align="center">true</td> | <td align="center" colspan="1" rowspan="1">true</td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>==</tt> implies <tt><=</tt></td> | <tt>==</tt> implies <tt><=</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>true > true</tt></td> | <tt>true > true</tt></td> | |||
<td align="center">false</td> | <td align="center" colspan="1" rowspan="1">false</td> | |||
<td align="center">Booleans do not offer <tt><</tt> compari | <td align="center" colspan="1" rowspan="1">Booleans do not off | |||
son</td> | er <tt><</tt> comparison</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>The second set of examples shows some complete JSONPath queries t | <t indent="0" pn="section-2.3.5.3-6">The second set of examples show | |||
hat make use | s some complete JSONPath queries that make use | |||
of filter selectors, and the results of evaluating these queries on a | of filter selectors and the results of evaluating these queries on a | |||
given JSON value as input. | given JSON value as input. | |||
(Note: two of the queries employ function extensions; please see | (Note: Two of the queries employ function extensions; please see | |||
Sections <xref format="counter" target="match"/> and <xref format="counter" targ | Sections <xref format="counter" target="match" sectionFormat="of" derivedContent | |||
et="search"/> below for details about these.)</t> | ="2.4.6"/> and <xref format="counter" target="search" sectionFormat="of" derived | |||
<t>JSON:</t> | Content="2.4.7"/> for details about these.)</t> | |||
<sourcecode type="json"><![CDATA[ | <t indent="0" pn="section-2.3.5.3-7">JSON:</t> | |||
<sourcecode type="json" markers="false" pn="section-2.3.5.3-8"> | ||||
{ | { | |||
"a": [3, 5, 1, 2, 4, 6, | "a": [3, 5, 1, 2, 4, 6, | |||
{"b": "j"}, | {"b": "j"}, | |||
{"b": "k"}, | {"b": "k"}, | |||
{"b": {}}, | {"b": {}}, | |||
{"b": "kilo"} | {"b": "kilo"} | |||
], | ], | |||
"o": {"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}}, | "o": {"p": 1, "q": 2, "r": 3, "s": 5, "t": {"u": 6}}, | |||
"e": "f" | "e": "f" | |||
} | } | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.3.5.3-9">Queries:</t> | |||
<t>The examples in <xref target="tbl-filter"/> show the filter selec | <t indent="0" pn="section-2.3.5.3-10">The examples in <xref target=" | |||
tor in use by a child segment:</t> | tbl-filter" format="default" sectionFormat="of" derivedContent="Table 12"/> show | |||
<table anchor="tbl-filter"> | the filter selector in use by a child segment.</t> | |||
<name>Filter selector examples</name> | <table anchor="tbl-filter" align="center" pn="table-12"> | |||
<name slugifiedName="name-filter-selector-examples">Filter Selecto | ||||
r Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?@.b == 'kilo']</tt></td> | <tt>$.a[?@.b == 'kilo']</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"b": "kilo"}</tt></td> | <tt>{"b": "kilo"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][9]</tt></td> | <tt>$['a'][9]</tt></td> | |||
<td align="left">Member value comparison</td> | <td align="left" colspan="1" rowspan="1">Member value comparis on</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?(@.b == 'kilo')]</tt></td> | <tt>$.a[?(@.b == 'kilo')]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"b": "kilo"}</tt></td> | <tt>{"b": "kilo"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][9]</tt></td> | <tt>$['a'][9]</tt></td> | |||
<td align="left">Equivalent query with enclosing parentheses</ td> | <td align="left" colspan="1" rowspan="1">Equivalent query with enclosing parentheses</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?@>3.5]</tt></td> | <tt>$.a[?@>3.5]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>5</tt> <br/> <tt>4</tt> <br/> <tt>6</tt></td> | <tt>5</tt> <br/> <tt>4</tt> <br/> <tt>6</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][1]</tt> <br/> <tt>$['a'][4]</tt> <br/> <tt>$['a'] [5]</tt></td> | <tt>$['a'][1]</tt> <br/> <tt>$['a'][4]</tt> <br/> <tt>$['a'] [5]</tt></td> | |||
<td align="left">Array value comparison</td> | <td align="left" colspan="1" rowspan="1">Array value compariso n</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?@.b]</tt></td> | <tt>$.a[?@.b]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b" : {}}</tt> <br/> <tt>{"b": "kilo"}</tt></td> | <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b" : {}}</tt> <br/> <tt>{"b": "kilo"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt> <br/> <tt>$['a'] [8]</tt> <br/> <tt>$['a'][9]</tt></td> | <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> | <td align="left" colspan="1" rowspan="1">Array value existence </td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?@.*]</tt></td> | <tt>$[?@.*]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<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> | <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"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a']</tt> <br/> <tt>$['o']</tt></td> | <tt>$['a']</tt> <br/> <tt>$['o']</tt></td> | |||
<td align="left">Existence of non-singular queries</td> | <td align="left" colspan="1" rowspan="1">Existence of non-sing ular queries</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?@[?@.b]]</tt></td> | <tt>$[?@[?@.b]]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[3, 5, 1, 2, 4, 6, {"b": "j"}, {"b": "k"}, {"b": {}}, {" b": "kilo"}]</tt></td> | <tt>[3, 5, 1, 2, 4, 6, {"b": "j"}, {"b": "k"}, {"b": {}}, {" b": "kilo"}]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a']</tt></td> | <tt>$['a']</tt></td> | |||
<td align="left">Nested filters</td> | <td align="left" colspan="1" rowspan="1">Nested filters</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[?@<3, ?@<3]</tt></td> | <tt>$.o[?@<3, ?@<3]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt ></td> | <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt ></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['p']</tt> <br/> <tt>$['o']['q']</tt> <br/> <tt>$[ 'o']['q']</tt> <br/> <tt>$['o']['p']</tt></td> | <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> | <td align="left" colspan="1" rowspan="1">Non-deterministic ord ering</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?@<2 || @.b == "k"]</tt></td> | <tt>$.a[?@<2 || @.b == "k"]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt> <br/> <tt>{"b": "k"}</tt></td> | <tt>1</tt> <br/> <tt>{"b": "k"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][2]</tt> <br/> <tt>$['a'][7]</tt></td> | <tt>$['a'][2]</tt> <br/> <tt>$['a'][7]</tt></td> | |||
<td align="left">Array value logical OR</td> | <td align="left" colspan="1" rowspan="1">Array value logical O R</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?match(@.b, "[jk]")]</tt></td> | <tt>$.a[?match(@.b, "[jk]")]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt></td> | <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt></td> | <tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt></td> | |||
<td align="left">Array value regular expression match</td> | <td align="left" colspan="1" rowspan="1">Array value regular e xpression match</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?search(@.b, "[jk]")]</tt></td> | <tt>$.a[?search(@.b, "[jk]")]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b" : "kilo"}</tt></td> | <tt>{"b": "j"}</tt> <br/> <tt>{"b": "k"}</tt> <br/> <tt>{"b" : "kilo"}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt> <br/> <tt>$['a'] [9]</tt></td> | <tt>$['a'][6]</tt> <br/> <tt>$['a'][7]</tt> <br/> <tt>$['a'] [9]</tt></td> | |||
<td align="left">Array value regular expression search</td> | <td align="left" colspan="1" rowspan="1">Array value regular e xpression search</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[?@>1 && @<4]</tt></td> | <tt>$.o[?@>1 && @<4]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>2</tt> <br/> <tt>3</tt></td> | <tt>2</tt> <br/> <tt>3</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['q']</tt> <br/> <tt>$['o']['r']</tt></td> | <tt>$['o']['q']</tt> <br/> <tt>$['o']['r']</tt></td> | |||
<td align="left">Object value logical AND</td> | <td align="left" colspan="1" rowspan="1">Object value logical AND</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[?@>1 && @<4]</tt></td> | <tt>$.o[?@>1 && @<4]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>3</tt> <br/> <tt>2</tt></td> | <tt>3</tt> <br/> <tt>2</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['r']</tt> <br/> <tt>$['o']['q']</tt></td> | <tt>$['o']['r']</tt> <br/> <tt>$['o']['q']</tt></td> | |||
<td align="left">Alternative result</td> | <td align="left" colspan="1" rowspan="1">Alternative result</t d> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o[?@.u || @.x]</tt></td> | <tt>$.o[?@.u || @.x]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"u": 6}</tt></td> | <tt>{"u": 6}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['t']</tt></td> | <tt>$['o']['t']</tt></td> | |||
<td align="left">Object value logical OR</td> | <td align="left" colspan="1" rowspan="1">Object value logical OR</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?@.b == $.x]</tt></td> | <tt>$.a[?@.b == $.x]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>3</tt> <br/> <tt>5</tt> <br/> <tt>1</tt> <br/> <tt>2</tt > <br/> <tt>4</tt> <br/> <tt>6</tt></td> | <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"> | <td align="center" colspan="1" rowspan="1"> | |||
<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]</t t></td> | <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]</t t></td> | |||
<td align="left">Comparison of queries with no values</td> | <td align="left" colspan="1" rowspan="1">Comparison of queries with no values</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[?@ == @]</tt></td> | <tt>$.a[?@ == @]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<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> | <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"> | <td align="center" colspan="1" rowspan="1"> | |||
<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> | <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 va lues</td> | <td align="left" colspan="1" rowspan="1">Comparisons of primit ive and of structured values</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>The example above with the query <tt>$.o[?@<3, ?@<3]</tt> s hows that a filter selector may produce nodelists in distinct | <t indent="0" pn="section-2.3.5.3-12">The example above with the que ry <tt>$.o[?@<3, ?@<3]</tt> shows that a filter selector may produce nodel ists in distinct | |||
orders each time it appears in the child segment.</t> | orders each time it appears in the child segment.</t> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="fnex"> | <section anchor="fnex" numbered="true" removeInRFC="false" toc="include" p | |||
<name>Function Extensions</name> | n="section-2.4"> | |||
<t>Beyond the filter expression functionality defined in the preceding | <name slugifiedName="name-function-extensions">Function Extensions</name | |||
> | ||||
<t indent="0" pn="section-2.4-1">Beyond the filter expression functional | ||||
ity defined in the preceding | ||||
subsections, JSONPath defines an extension point that can be used to | subsections, JSONPath defines an extension point that can be used to | |||
add filter expression functionality: "Function Extensions".</t> | add filter expression functionality: "Function Extensions".</t> | |||
<t>This section defines the extension point as well as some function | <t indent="0" pn="section-2.4-2">This section defines the extension poin t and some function | |||
extensions that use this extension point. | extensions that use this extension point. | |||
While these mechanisms are designed to use the extension point, | While these mechanisms are designed to use the extension point, | |||
they are an integral part of the JSONPath specification and are | they are an integral part of the JSONPath specification and are | |||
expected to be implemented like any other integral part of this | expected to be implemented like any other integral part of this | |||
specification.</t> | specification.</t> | |||
<t>A function extension defines a registered name (see <xref target="ian a-fnex"/>) that | <t indent="0" pn="section-2.4-3">A function extension defines a register ed name (see <xref target="iana-fnex" format="default" sectionFormat="of" derive dContent="Section 3.2"/>) that | |||
can be applied to a sequence of zero or more arguments, producing a | can be applied to a sequence of zero or more arguments, producing a | |||
result. Each registered function name is unique.</t> | result. Each registered function name is unique.</t> | |||
<t>A function extension <bcp14>MUST</bcp14> be defined such that its eva | <t indent="0" pn="section-2.4-4">A function extension <bcp14>MUST</bcp14 | |||
luation is | > be defined such that its evaluation is | |||
side-effect free, i.e., all possible orders of evaluation and choices | free of side effects, i.e., all possible orders of evaluation and choices | |||
of short-circuiting or full evaluation of an expression containing it | of short-circuiting or full evaluation of an expression containing it | |||
<bcp14>MUST</bcp14> lead to the same result. | <bcp14>MUST</bcp14> lead to the same result. | |||
(Note: memoization or logging are not side effects in this sense | (Note: Memoization or logging are not side effects in this sense | |||
as they are visible at the implementation level only — they do not | as they are visible at the implementation level only -- they do not | |||
influence the result of the evaluation.)</t> | influence the result of the evaluation.)</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="false" p n="section-2.4-5"> | |||
function-name = function-name-first *function-name-char | function-name = function-name-first *function-name-char | |||
function-name-first = LCALPHA | function-name-first = LCALPHA | |||
function-name-char = function-name-first / "_" / DIGIT | function-name-char = function-name-first / "_" / DIGIT | |||
LCALPHA = %x61-7A ; "a".."z" | LCALPHA = %x61-7A ; "a".."z" | |||
function-expr = function-name "(" S [function-argument | function-expr = function-name "(" S [function-argument | |||
*(S "," S function-argument)] S ")" | *(S "," S function-argument)] S ")" | |||
function-argument = literal / | function-argument = literal / | |||
filter-query / ; (includes singular-query) | filter-query / ; (includes singular-query) | |||
logical-expr / | logical-expr / | |||
function-expr | function-expr | |||
]]></sourcecode> | </sourcecode> | |||
<t>Any function expressions in a query must be well-formed (by conformin | <t indent="0" pn="section-2.4-6">Any function expressions in a query mus | |||
g to the above ABNF) | t be well-formed (by conforming to the above ABNF) | |||
and well-typed, | and well-typed; | |||
otherwise the JSONPath implementation <bcp14>MUST</bcp14> raise an error | otherwise, the JSONPath implementation <bcp14>MUST</bcp14> raise an error | |||
(see <xref target="synsem-overview"/>). | (see <xref target="synsem-overview" format="default" sectionFormat="of" derivedC | |||
ontent="Section 2.1"/>). | ||||
To define which function expressions are well-typed, | To define which function expressions are well-typed, | |||
a type system is first introduced.</t> | a type system is first introduced.</t> | |||
<section anchor="typesys"> | <section anchor="typesys" numbered="true" removeInRFC="false" toc="inclu | |||
<name>Type System for Function Expressions</name> | de" pn="section-2.4.1"> | |||
<t>Each parameter as well as the result of a function extension must h | <name slugifiedName="name-type-system-for-function-ex">Type System for | |||
ave a declared type.</t> | Function Expressions</name> | |||
<t>Declared types enable checking a JSONPath query for well-typedness | <t indent="0" pn="section-2.4.1-1">Each parameter and the result of a | |||
function extension must have a declared type.</t> | ||||
<t indent="0" pn="section-2.4.1-2">Declared types enable checking a JS | ||||
ONPath query for well-typedness | ||||
independent of any query argument the JSONPath query is applied to.</t> | independent of any query argument the JSONPath query is applied to.</t> | |||
<t><xref target="tbl-types"/> defines the available types in terms of | <t indent="0" pn="section-2.4.1-3"><xref target="tbl-types" format="de | |||
the instances they contain.</t> | fault" sectionFormat="of" derivedContent="Table 13"/> defines the available type | |||
<table anchor="tbl-types"> | s in terms of the instances they contain.</t> | |||
<name>Function extension type system</name> | <table anchor="tbl-types" align="center" pn="table-13"> | |||
<name slugifiedName="name-function-extension-type-sys">Function Exte | ||||
nsion Type System</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">Type</th> | <th align="left" colspan="1" rowspan="1">Type</th> | |||
<th align="left">Instances</th> | <th align="left" colspan="1" rowspan="1">Instances</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>ValueType</tt></td> | <tt>ValueType</tt></td> | |||
<td align="left">JSON values or <tt>Nothing</tt></td> | <td align="left" colspan="1" rowspan="1">JSON values or <tt>Noth ing</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>LogicalType</tt></td> | <tt>LogicalType</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>LogicalTrue</tt> or <tt>LogicalFalse</tt></td> | <tt>LogicalTrue</tt> or <tt>LogicalFalse</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>NodesType</tt></td> | <tt>NodesType</tt></td> | |||
<td align="left">Nodelists</td> | <td align="left" colspan="1" rowspan="1">Nodelists</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>Notes:</t> | <t indent="0" pn="section-2.4.1-5">Notes:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section | |||
<li>The only instances that can be directly represented in JSONPath | -2.4.1-6"> | |||
syntax are certain JSON values | <li pn="section-2.4.1-6.1">The only instances that can be directly r | |||
epresented in JSONPath syntax are certain JSON values | ||||
in <tt>ValueType</tt> expressed as literals (which, in JSONPath, are limited to primitive values).</li> | 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 | <li pn="section-2.4.1-6.2">The special result <tt>Nothing</tt> repre | |||
JSON value and is distinct from any JSON value, including <tt>null</tt>.</li> | sents the absence of a JSON value and is distinct from any JSON value, including | |||
<li> | <tt>null</tt>.</li> | |||
<li pn="section-2.4.1-6.3"> | ||||
<tt>LogicalTrue</tt> and <tt>LogicalFalse</tt> are unrelated to th e JSON values expressed by the | <tt>LogicalTrue</tt> and <tt>LogicalFalse</tt> are unrelated to th e JSON values expressed by the | |||
literals <tt>true</tt> and <tt>false</tt>.</li> | literals <tt>true</tt> and <tt>false</tt>.</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="type-conv"> | <section anchor="type-conv" numbered="true" removeInRFC="false" toc="inc | |||
<name>Type Conversion</name> | lude" pn="section-2.4.2"> | |||
<t>Just as queries can be used in logical expressions by testing for t | <name slugifiedName="name-type-conversion">Type Conversion</name> | |||
he | <t indent="0" pn="section-2.4.2-1">Just as queries can be used in logi | |||
existence of at least one node (<xref target="extest"/>), a function expression | cal expressions by testing for the | |||
of | existence of at least one node (<xref target="extest" format="default" sectionFo | |||
rmat="of" derivedContent="Section 2.3.5.2.1"/>), a function expression of | ||||
declared type <tt>NodesType</tt> can be used as a function argument for a | 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> | parameter of declared type <tt>LogicalType</tt>, with the equivalent conversion rule:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section | |||
<li>If the nodelist contains one or more nodes, the conversion resul | -2.4.2-2"> | |||
t is <tt>LogicalTrue</tt>.</li> | <li pn="section-2.4.2-2.1">If the nodelist contains one or more node | |||
<li>If the nodelist is empty, the conversion result is <tt>LogicalFa | s, the conversion result is <tt>LogicalTrue</tt>.</li> | |||
lse</tt>.</li> | <li pn="section-2.4.2-2.2">If the nodelist is empty, the conversion | |||
result is <tt>LogicalFalse</tt>.</li> | ||||
</ul> | </ul> | |||
<t>Notes:</t> | <t indent="0" pn="section-2.4.2-3">Notes:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section | |||
<li>Extraction of a value from a nodelist can be performed in severa | -2.4.2-4"> | |||
l | <li pn="section-2.4.2-4.1">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> | ways, so an implicit conversion from <tt>NodesType</tt> to <tt>ValueType</tt> | |||
may be surprising and has therefore not been defined.</li> | may be surprising and has therefore not been defined.</li> | |||
<li>A function expression with a declared type of <tt>NodesType</tt> can | <li pn="section-2.4.2-4.2">A function expression with a declared typ e of <tt>NodesType</tt> can | |||
indirectly be used as an argument for a parameter of declared type | 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, | <tt>ValueType</tt> by wrapping the expression in a call to a function extension, | |||
such as <tt>value()</tt> (see <xref target="value"/>), | such as <tt>value()</tt> (see <xref target="value" format="default" sectionForma t="of" derivedContent="Section 2.4.8"/>), | |||
that takes a parameter of type <tt>NodesType</tt> and returns a | that takes a parameter of type <tt>NodesType</tt> and returns a | |||
result of type <tt>ValueType</tt>.</li> | result of type <tt>ValueType</tt>.</li> | |||
</ul> | </ul> | |||
<t>The well-typedness of function expressions can now be defined in te rms of this type system.</t> | <t indent="0" pn="section-2.4.2-5">The well-typedness of function expr essions can now be defined in terms of this type system.</t> | |||
</section> | </section> | |||
<section anchor="well-typedness"> | <section anchor="well-typedness" numbered="true" removeInRFC="false" toc | |||
<name>Well-Typedness of Function Expressions</name> | ="include" pn="section-2.4.3"> | |||
<t>For a function expression to be well-typed:</t> | <name slugifiedName="name-well-typedness-of-function-">Well-Typedness | |||
<ol spacing="normal" type="1"><li>its declared type must be well-typed | of Function Expressions</name> | |||
in the context in which it occurs, and</li> | <t indent="0" pn="section-2.4.3-1">For a function expression to be wel | |||
<li>its arguments must be well-typed for the declared type of the co | l-typed:</t> | |||
rresponding parameters.</li> | <ol spacing="normal" type="1" indent="adaptive" start="1" pn="section- | |||
</ol> | 2.4.3-2"> | |||
<t>(1) As per the grammar, a function expression can occur in three di | <li pn="section-2.4.3-2.1" derivedCounter="1."> | |||
fferent | <t indent="0" pn="section-2.4.3-2.1.1">Its declared type must be w | |||
ell-typed in the context in which it occurs.</t> | ||||
<t indent="0" pn="section-2.4.3-2.1.2">As per the grammar, a funct | ||||
ion expression can occur in three different | ||||
immediate contexts, which lead to the following conditions for well-typedness:</ t> | immediate contexts, which lead to the following conditions for well-typedness:</ t> | |||
<dl newline="true"> | <dl newline="true" indent="3" spacing="normal" pn="section-2.4.3-2 | |||
<dt>As a <tt>test-expr</tt> in a logical expression:</dt> | .1.3"> | |||
<dd> | <dt pn="section-2.4.3-2.1.3.1">As a <tt>test-expr</tt> in a logi | |||
<t>The function's declared result type is <tt>LogicalType</tt>, or | cal expression:</dt> | |||
(giving rise to conversion as per <xref target="type-conv"/>) <tt>NodesType</tt> | <dd pn="section-2.4.3-2.1.3.2"> | |||
.</t> | <t indent="0" pn="section-2.4.3-2.1.3.2.1">The function's decl | |||
</dd> | ared result type is <tt>LogicalType</tt> or | |||
<dt>As a <tt>comparable</tt> in a comparison:</dt> | (giving rise to conversion as per <xref target="type-conv" format="default" sect | |||
<dd> | ionFormat="of" derivedContent="Section 2.4.2"/>) <tt>NodesType</tt>.</t> | |||
<t>The function's declared result type is <tt>ValueType</tt>.</t> | </dd> | |||
</dd> | <dt pn="section-2.4.3-2.1.3.3">As a <tt>comparable</tt> in a com | |||
<dt>As a <tt>function-argument</tt> in another function expression:< | parison:</dt> | |||
/dt> | <dd pn="section-2.4.3-2.1.3.4"> | |||
<dd> | <t indent="0" pn="section-2.4.3-2.1.3.4.1">The function's decl | |||
<t>The function's declared result type fulfills the following rule | ared result type is <tt>ValueType</tt>.</t> | |||
s for | </dd> | |||
<dt pn="section-2.4.3-2.1.3.5">As a <tt>function-argument</tt> i | ||||
n another function expression:</dt> | ||||
<dd pn="section-2.4.3-2.1.3.6"> | ||||
<t indent="0" pn="section-2.4.3-2.1.3.6.1">The function's decl | ||||
ared result type fulfills the following rules for | ||||
the corresponding parameter of the enclosing function.</t> | the corresponding parameter of the enclosing function.</t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>(2) The arguments of the function expression are well-typed when | </li> | |||
<li pn="section-2.4.3-2.2" derivedCounter="2."> | ||||
<t indent="0" pn="section-2.4.3-2.2.1">Its arguments must be well- | ||||
typed for the declared type of the corresponding parameters.</t> | ||||
<t indent="0" pn="section-2.4.3-2.2.2">The arguments of the functi | ||||
on expression are well-typed when | ||||
each argument of the function can be used for the declared type of the | each argument of the function can be used for the declared type of the | |||
corresponding parameter, according to one of the following | corresponding parameter, according to one of the following | |||
conditions:</t> | conditions:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="sec | |||
<li>When the argument is a function expression with declared result | tion-2.4.3-2.2.3"> | |||
type the same as the | <li pn="section-2.4.3-2.2.3.1">When the argument is a function e | |||
xpression with the same declared result type as the | ||||
declared type of the parameter.</li> | declared type of the parameter.</li> | |||
<li> | <li pn="section-2.4.3-2.2.3.2"> | |||
<t>When the declared type of the parameter is <tt>LogicalType</tt> | <t indent="0" pn="section-2.4.3-2.2.3.2.1">When the declared t | |||
and the argument is one of the following: | ype of the parameter is <tt>LogicalType</tt> and the argument is one of the foll | |||
</t> | owing: | |||
<ul spacing="normal"> | </t> | |||
<li>A function expression with declared result type <tt>NodesTyp | <ul spacing="normal" bare="false" empty="false" indent="3" pn= | |||
e</tt>. | "section-2.4.3-2.2.3.2.2"> | |||
In this case the argument is converted to LogicalType as per <xref target="type- | <li pn="section-2.4.3-2.2.3.2.2.1">A function expression wit | |||
conv"/>.</li> | h declared result type <tt>NodesType</tt>. | |||
<li>A <tt>logical-expr</tt> that is not a function expression.</ | In this case, the argument is converted to LogicalType as per <xref target="type | |||
li> | -conv" format="default" sectionFormat="of" derivedContent="Section 2.4.2"/>.</li | |||
</ul> | > | |||
</li> | <li pn="section-2.4.3-2.2.3.2.2.2">A <tt>logical-expr</tt> t | |||
<li>When the declared type of the parameter is <tt>NodesType</tt> an | hat is not a function expression.</li> | |||
d the argument is a query | </ul> | |||
</li> | ||||
<li pn="section-2.4.3-2.2.3.3">When the declared type of the par | ||||
ameter is <tt>NodesType</tt> and the argument is a query | ||||
(which includes singular query).</li> | (which includes singular query).</li> | |||
<li> | <li pn="section-2.4.3-2.2.3.4"> | |||
<t>When the declared type of the parameter is <tt>ValueType</tt> a | <t indent="0" pn="section-2.4.3-2.2.3.4.1">When the declared t | |||
nd the argument is one of the following: | ype of the parameter is <tt>ValueType</tt> and the argument is one of the follow | |||
</t> | ing: | |||
<ul spacing="normal"> | ||||
<li>A value expressed as a literal.</li> | ||||
<li> | ||||
<t>A singular query. In this case: | ||||
</t> | </t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn= | |||
<li>If the query results in a nodelist consisting of a singl | "section-2.4.3-2.2.3.4.2"> | |||
e node, the | <li pn="section-2.4.3-2.2.3.4.2.1">A value expressed as a li | |||
teral.</li> | ||||
<li pn="section-2.4.3-2.2.3.4.2.2"> | ||||
<t indent="0" pn="section-2.4.3-2.2.3.4.2.2.1">A singular | ||||
query. In this case: | ||||
</t> | ||||
<ul spacing="normal" bare="false" empty="false" indent="3" | ||||
pn="section-2.4.3-2.2.3.4.2.2.2"> | ||||
<li pn="section-2.4.3-2.2.3.4.2.2.2.1">If the query resu | ||||
lts in a nodelist consisting of a single node, the | ||||
argument is the value of the node.</li> | argument is the value of the node.</li> | |||
<li>If the query results in an empty nodelist, the argument is | <li pn="section-2.4.3-2.2.3.4.2.2.2.2">If the query resu lts in an empty nodelist, the argument is | |||
the special result <tt>Nothing</tt>.</li> | the special result <tt>Nothing</tt>.</li> | |||
</ul> | ||||
</li> | ||||
</ul> | </ul> | |||
</li> | </li> | |||
</ul> | </ul> | |||
</li> | </li> | |||
</ul> | </ol> | |||
</section> | </section> | |||
<section anchor="length"> | <section anchor="length" numbered="true" removeInRFC="false" toc="includ | |||
<name><tt>length()</tt> Function Extension</name> | e" pn="section-2.4.4"> | |||
<dl> | <name slugifiedName="name-length-function-extension"><tt>length()</tt> | |||
<dt>Parameters:</dt> | Function Extension</name> | |||
<dd> | <dl indent="3" newline="false" spacing="normal" pn="section-2.4.4-1"> | |||
<ol spacing="normal" type="1"><li> | <dt pn="section-2.4.4-1.1">Parameters:</dt> | |||
<dd pn="section-2.4.4-1.2"> | ||||
<ol spacing="normal" type="1" indent="adaptive" start="1" pn="sect | ||||
ion-2.4.4-1.2.1"><li pn="section-2.4.4-1.2.1.1" derivedCounter="1."> | ||||
<tt>ValueType</tt></li> | <tt>ValueType</tt></li> | |||
</ol> | </ol> | |||
</dd> | </dd> | |||
<dt>Result:</dt> | <dt pn="section-2.4.4-1.3">Result:</dt> | |||
<dd> | <dd pn="section-2.4.4-1.4"> | |||
<t><tt>ValueType</tt> (unsigned integer or <tt>Nothing</tt>)</t> | <t indent="0" pn="section-2.4.4-1.4.1"><tt>ValueType</tt> (unsigne | |||
d integer or <tt>Nothing</tt>)</t> | ||||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>The <tt>length()</tt> function extension provides a way to compute the length | <t indent="0" pn="section-2.4.4-2">The <tt>length()</tt> function exte nsion provides a way to compute the length | |||
of a value and make that available for further processing in the | of a value and make that available for further processing in the | |||
filter expression:</t> | filter expression:</t> | |||
<sourcecode type="JSONPath"><![CDATA[ | <sourcecode type="application/jsonpath" markers="false" pn="section-2. | |||
$[?length(@.authors) >= 5] | 4.4-3"> | |||
]]></sourcecode> | $[?length(@.authors) >= 5] | |||
<t>Its only argument is an instance of <tt>ValueType</tt> (possibly ta | </sourcecode> | |||
ken from a | <t indent="0" pn="section-2.4.4-4">Its only argument is an instance of | |||
singular query, as in the example above). The result also is an | <tt>ValueType</tt> (possibly taken from a | |||
singular query, as in the example above). The result is also an | ||||
instance of <tt>ValueType</tt>: an unsigned integer or the special result <tt>No thing</tt>.</t> | instance of <tt>ValueType</tt>: an unsigned integer or the special result <tt>No thing</tt>.</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section | |||
<li>If the argument value is a string, the result is the number of | -2.4.4-5"> | |||
<li pn="section-2.4.4-5.1">If the argument value is a string, the re | ||||
sult is the number of | ||||
Unicode scalar values in the string.</li> | Unicode scalar values in the string.</li> | |||
<li>If the argument value is an array, the result is the number of | <li pn="section-2.4.4-5.2">If the argument value is an array, the re sult is the number of | |||
elements in the array.</li> | elements in the array.</li> | |||
<li>If the argument value is an object, the result is the number of | <li pn="section-2.4.4-5.3">If the argument value is an object, the r esult is the number of | |||
members in the object.</li> | members in the object.</li> | |||
<li>For any other argument value, the result is the special result < tt>Nothing</tt>.</li> | <li pn="section-2.4.4-5.4">For any other argument value, the result is the special result <tt>Nothing</tt>.</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="count"> | <section anchor="count" numbered="true" removeInRFC="false" toc="include | |||
<name><tt>count()</tt> Function Extension</name> | " pn="section-2.4.5"> | |||
<dl> | <name slugifiedName="name-count-function-extension"><tt>count()</tt> F | |||
<dt>Parameters:</dt> | unction Extension</name> | |||
<dd> | <dl indent="3" newline="false" spacing="normal" pn="section-2.4.5-1"> | |||
<ol spacing="normal" type="1"><li> | <dt pn="section-2.4.5-1.1">Parameters:</dt> | |||
<dd pn="section-2.4.5-1.2"> | ||||
<ol spacing="normal" type="1" indent="adaptive" start="1" pn="sect | ||||
ion-2.4.5-1.2.1"><li pn="section-2.4.5-1.2.1.1" derivedCounter="1."> | ||||
<tt>NodesType</tt></li> | <tt>NodesType</tt></li> | |||
</ol> | </ol> | |||
</dd> | </dd> | |||
<dt>Result:</dt> | <dt pn="section-2.4.5-1.3">Result:</dt> | |||
<dd> | <dd pn="section-2.4.5-1.4"> | |||
<t><tt>ValueType</tt> (unsigned integer)</t> | <t indent="0" pn="section-2.4.5-1.4.1"><tt>ValueType</tt> (unsigne | |||
d integer)</t> | ||||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>The <tt>count()</tt> function extension provides a way to obtain th e number of | <t indent="0" pn="section-2.4.5-2">The <tt>count()</tt> function exten sion provides a way to obtain the number of | |||
nodes in a nodelist and make that available for further processing in | nodes in a nodelist and make that available for further processing in | |||
the filter expression:</t> | the filter expression:</t> | |||
<sourcecode type="JSONPath"><![CDATA[ | <sourcecode type="application/jsonpath" markers="false" pn="section-2. | |||
$[?count(@.*.author) >= 5] | 4.5-3"> | |||
]]></sourcecode> | $[?count(@.*.author) >= 5] | |||
<t>Its only argument is a nodelist. | </sourcecode> | |||
The result is a value, an unsigned integer, that gives the number of | <t indent="0" pn="section-2.4.5-4">Its only argument is a nodelist. | |||
nodes in the nodelist. | The result is a value (an unsigned integer) that gives the number of | |||
Notes:</t> | nodes in the nodelist.</t> | |||
<ul spacing="normal"> | <t indent="0" pn="section-2.4.5-5">Notes:</t> | |||
<li>There is no deduplication of the nodelist.</li> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section | |||
<li>The number of nodes in the nodelist is counted independent of th | -2.4.5-6"> | |||
eir | <li pn="section-2.4.5-6.1">There is no deduplication of the nodelist | |||
values or any children they may have; e.g., the count of a non-empty | .</li> | |||
<li pn="section-2.4.5-6.2">The number of nodes in the nodelist is co | ||||
unted independent of their | ||||
values or any children they may have, e.g., the count of a non-empty | ||||
singular nodelist such as <tt>count(@)</tt> is always 1.</li> | singular nodelist such as <tt>count(@)</tt> is always 1.</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
<section anchor="match"> | <section anchor="match" numbered="true" removeInRFC="false" toc="include | |||
<name><tt>match()</tt> Function Extension</name> | " pn="section-2.4.6"> | |||
<dl> | <name slugifiedName="name-match-function-extension"><tt>match()</tt> F | |||
<dt>Parameters:</dt> | unction Extension</name> | |||
<dd> | <dl indent="3" newline="false" spacing="normal" pn="section-2.4.6-1"> | |||
<ol spacing="normal" type="1"><li> | <dt pn="section-2.4.6-1.1">Parameters:</dt> | |||
<dd pn="section-2.4.6-1.2"> | ||||
<ol spacing="normal" type="1" indent="adaptive" start="1" pn="sect | ||||
ion-2.4.6-1.2.1"><li pn="section-2.4.6-1.2.1.1" derivedCounter="1."> | ||||
<tt>ValueType</tt> (string)</li> | <tt>ValueType</tt> (string)</li> | |||
<li> | <li pn="section-2.4.6-1.2.1.2" derivedCounter="2."> | |||
<tt>ValueType</tt> (string conforming to <xref target="I-D.dra | <tt>ValueType</tt> (string conforming to <xref target="RFC9485 | |||
ft-ietf-jsonpath-iregexp"/>)</li> | " format="default" sectionFormat="of" derivedContent="RFC9485"/>)</li> | |||
</ol> | </ol> | |||
</dd> | </dd> | |||
<dt>Result:</dt> | <dt pn="section-2.4.6-1.3">Result:</dt> | |||
<dd> | <dd pn="section-2.4.6-1.4"> | |||
<t><tt>LogicalType</tt></t> | <t indent="0" pn="section-2.4.6-1.4.1"><tt>LogicalType</tt></t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>The <tt>match()</tt> function extension provides a way to check whe | <t indent="0" pn="section-2.4.6-2">The <tt>match()</tt> function exten | |||
ther (the | sion provides a way to check whether (the | |||
entirety of, see <xref target="search"/> below) a given | entirety of; see <xref target="search" format="default" sectionFormat="of" deriv | |||
string matches a given regular expression, which is in <xref target="I-D.draft-i | edContent="Section 2.4.7"/>) a given | |||
etf-jsonpath-iregexp"/> form.</t> | string matches a given regular expression, which is in the form described in <xr | |||
<sourcecode type="JSONPath"><![CDATA[ | ef target="RFC9485" format="default" sectionFormat="of" derivedContent="RFC9485" | |||
/>.</t> | ||||
<sourcecode type="application/jsonpath" markers="false" pn="section-2. | ||||
4.6-3"> | ||||
$[?match(@.date, "1974-05-..")] | $[?match(@.date, "1974-05-..")] | |||
]]></sourcecode> | </sourcecode> | |||
<t>Its arguments are instances of <tt>ValueType</tt> (possibly taken f | <t indent="0" pn="section-2.4.6-4">Its arguments are instances of <tt> | |||
rom a | ValueType</tt> (possibly taken from a | |||
singular query, as for the first argument in the example above). | singular query, as for the first argument in the example above). | |||
If the first argument is not a string or the second argument is not a | If the first argument is not a string or the second argument is not a | |||
string conforming to <xref target="I-D.draft-ietf-jsonpath-iregexp"/>, the resul t is <tt>LogicalFalse</tt>. | string conforming to <xref target="RFC9485" format="default" sectionFormat="of" derivedContent="RFC9485"/>, the result is <tt>LogicalFalse</tt>. | |||
Otherwise, the string that is the first argument is matched against | Otherwise, the string that is the first argument is matched against | |||
the iregexp contained in the string that is the second argument; | the I-Regexp contained in the string that is the second argument; | |||
the result is <tt>LogicalTrue</tt> if the string matches the iregexp and | the result is <tt>LogicalTrue</tt> if the string matches the I-Regexp and is | |||
<tt>LogicalFalse</tt> otherwise.</t> | <tt>LogicalFalse</tt> otherwise.</t> | |||
</section> | </section> | |||
<section anchor="search"> | <section anchor="search" numbered="true" removeInRFC="false" toc="includ | |||
<name><tt>search()</tt> Function Extension</name> | e" pn="section-2.4.7"> | |||
<dl> | <name slugifiedName="name-search-function-extension"><tt>search()</tt> | |||
<dt>Parameters:</dt> | Function Extension</name> | |||
<dd> | <dl indent="3" newline="false" spacing="normal" pn="section-2.4.7-1"> | |||
<ol spacing="normal" type="1"><li> | <dt pn="section-2.4.7-1.1">Parameters:</dt> | |||
<dd pn="section-2.4.7-1.2"> | ||||
<ol spacing="normal" type="1" indent="adaptive" start="1" pn="sect | ||||
ion-2.4.7-1.2.1"><li pn="section-2.4.7-1.2.1.1" derivedCounter="1."> | ||||
<tt>ValueType</tt> (string)</li> | <tt>ValueType</tt> (string)</li> | |||
<li> | <li pn="section-2.4.7-1.2.1.2" derivedCounter="2."> | |||
<tt>ValueType</tt> (string conforming to <xref target="I-D.dra | <tt>ValueType</tt> (string conforming to <xref target="RFC9485 | |||
ft-ietf-jsonpath-iregexp"/>)</li> | " format="default" sectionFormat="of" derivedContent="RFC9485"/>)</li> | |||
</ol> | </ol> | |||
</dd> | </dd> | |||
<dt>Result:</dt> | <dt pn="section-2.4.7-1.3">Result:</dt> | |||
<dd> | <dd pn="section-2.4.7-1.4"> | |||
<t><tt>LogicalType</tt></t> | <t indent="0" pn="section-2.4.7-1.4.1"><tt>LogicalType</tt></t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>The <tt>search()</tt> function extension provides a way to check wh ether a | <t indent="0" pn="section-2.4.7-2">The <tt>search()</tt> function exte nsion provides a way to check whether a | |||
given string contains a substring that matches a given regular | given string contains a substring that matches a given regular | |||
expression, which is in <xref target="I-D.draft-ietf-jsonpath-iregexp"/> form.</ | expression, which is in the form described in <xref target="RFC9485" format="def | |||
t> | ault" sectionFormat="of" derivedContent="RFC9485"/>.</t> | |||
<sourcecode type="JSONPath"><![CDATA[ | <sourcecode type="application/jsonpath" markers="false" pn="section-2. | |||
4.7-3"> | ||||
$[?search(@.author, "[BR]ob")] | $[?search(@.author, "[BR]ob")] | |||
]]></sourcecode> | </sourcecode> | |||
<t>Its arguments are instances of <tt>ValueType</tt> (possibly taken f | <t indent="0" pn="section-2.4.7-4">Its arguments are instances of <tt> | |||
rom a | ValueType</tt> (possibly taken from a | |||
singular query, as for the first argument in the example above). | singular query, as for the first argument in the example above). | |||
If the first argument is not a string or the second argument is not a | If the first argument is not a string or the second argument is not a | |||
string conforming to <xref target="I-D.draft-ietf-jsonpath-iregexp"/>, the resul | string conforming to <xref target="RFC9485" format="default" sectionFormat="of" | |||
t is <tt>LogicalFalse</tt>. | derivedContent="RFC9485"/>, the result is <tt>LogicalFalse</tt>. | |||
Otherwise, the string that is the first argument is searched for at | Otherwise, the string that is the first argument is searched for a | |||
least one substring that matches the iregexp contained in the string | substring that matches the I-Regexp contained in the string | |||
that is the second argument; the result is <tt>LogicalTrue</tt> if such a | that is the second argument; the result is <tt>LogicalTrue</tt> if at | |||
substring exists and <tt>LogicalFalse</tt> otherwise.</t> | least one such substring exists and is <tt>LogicalFalse</tt> otherwise.</t> | |||
</section> | </section> | |||
<section anchor="value"> | <section anchor="value" numbered="true" removeInRFC="false" toc="include | |||
<name><tt>value()</tt> Function Extension</name> | " pn="section-2.4.8"> | |||
<dl> | <name slugifiedName="name-value-function-extension"><tt>value()</tt> F | |||
<dt>Parameters:</dt> | unction Extension</name> | |||
<dd> | <dl indent="3" newline="false" spacing="normal" pn="section-2.4.8-1"> | |||
<ol spacing="normal" type="1"><li> | <dt pn="section-2.4.8-1.1">Parameters:</dt> | |||
<dd pn="section-2.4.8-1.2"> | ||||
<ol spacing="normal" type="1" indent="adaptive" start="1" pn="sect | ||||
ion-2.4.8-1.2.1"><li pn="section-2.4.8-1.2.1.1" derivedCounter="1."> | ||||
<tt>NodesType</tt></li> | <tt>NodesType</tt></li> | |||
</ol> | </ol> | |||
</dd> | </dd> | |||
<dt>Result:</dt> | <dt pn="section-2.4.8-1.3">Result:</dt> | |||
<dd> | <dd pn="section-2.4.8-1.4"> | |||
<t><tt>ValueType</tt></t> | <t indent="0" pn="section-2.4.8-1.4.1"><tt>ValueType</tt></t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>The <tt>value()</tt> function extension provides a way to convert a n instance of <tt>NodesType</tt> to a value and | <t indent="0" pn="section-2.4.8-2">The <tt>value()</tt> function exten sion 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> | make that available for further processing in the filter expression:</t> | |||
<sourcecode type="JSONPath"><![CDATA[ | <sourcecode type="application/jsonpath" markers="false" pn="section-2. 4.8-3"> | |||
$[?value(@..color) == "red"] | $[?value(@..color) == "red"] | |||
]]></sourcecode> | </sourcecode> | |||
<t>Its only argument is an instance of <tt>NodesType</tt> (possibly ta | <t indent="0" pn="section-2.4.8-4">Its only argument is an instance of | |||
ken from a | <tt>NodesType</tt> (possibly taken from a | |||
<tt>filter-query</tt>, as in the example above). The result is an | <tt>filter-query</tt>, as in the example above). The result is an | |||
instance of <tt>ValueType</tt>.</t> | instance of <tt>ValueType</tt>.</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section | |||
<li>If the argument contains a single node, the result is | -2.4.8-5"> | |||
<li pn="section-2.4.8-5.1">If the argument contains a single node, t | ||||
he result is | ||||
the value of the node.</li> | the value of the node.</li> | |||
<li>If the argument is the special result <tt>Nothing</tt> or contai ns multiple nodes, the | <li pn="section-2.4.8-5.2">If the argument is the empty nodelist or contains multiple nodes, the | |||
result is <tt>Nothing</tt>.</li> | result is <tt>Nothing</tt>.</li> | |||
</ul> | </ul> | |||
<t>Note: a singular query may be used anywhere where a ValueType is ex pected, | <t indent="0" pn="section-2.4.8-6">Note: A 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 singul ar query.</t> | so there is no need to use the <tt>value()</tt> function extension with a singul ar query.</t> | |||
</section> | </section> | |||
<section anchor="examples-6"> | <section anchor="examples-6" numbered="true" removeInRFC="false" toc="in | |||
<name>Examples</name> | clude" pn="section-2.4.9"> | |||
<table anchor="tbl-function-expr"> | <name slugifiedName="name-examples-7">Examples</name> | |||
<name>Function expression examples</name> | <table anchor="tbl-function-expr" align="center" pn="table-14"> | |||
<name slugifiedName="name-function-expression-example">Function Expr | ||||
ession Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?length(@) < 3]</tt></td> | <tt>$[?length(@) < 3]</tt></td> | |||
<td align="left">well-typed</td> | <td align="left" colspan="1" rowspan="1">well-typed</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?length(@.*) < 3]</tt></td> | <tt>$[?length(@.*) < 3]</tt></td> | |||
<td align="left">not well-typed since <tt>@.*</tt> is a non-sing ular query</td> | <td align="left" colspan="1" rowspan="1">not well-typed since <t t>@.*</tt> is a non-singular query</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?count(@.*) == 1]</tt></td> | <tt>$[?count(@.*) == 1]</tt></td> | |||
<td align="left">well-typed</td> | <td align="left" colspan="1" rowspan="1">well-typed</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?count(1) == 1]</tt></td> | <tt>$[?count(1) == 1]</tt></td> | |||
<td align="left">not well-typed since <tt>1</tt> is not a query or function expression</td> | <td align="left" colspan="1" rowspan="1">not well-typed since <t t>1</tt> is not a query or function expression</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?count(foo(@.*)) == 1]</tt></td> | <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>NodesT ype</tt></td> | <td align="left" colspan="1" rowspan="1">well-typed, where <tt>f oo()</tt> is a function extension with a parameter of type <tt>NodesType</tt> an d result type <tt>NodesType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?match(@.timezone, 'Europe/.*')]</tt></td> | <tt>$[?match(@.timezone, 'Europe/.*')]</tt></td> | |||
<td align="left">well-typed</td> | <td align="left" colspan="1" rowspan="1">well-typed</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?match(@.timezone, 'Europe/.*') == true]</tt></td> | <tt>$[?match(@.timezone, 'Europe/.*') == true]</tt></td> | |||
<td align="left">not well-typed as <tt>LogicalType</tt> may not be used in comparisons</td> | <td align="left" colspan="1" rowspan="1">not well-typed as <tt>L ogicalType</tt> may not be used in comparisons</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?value(@..color) == "red"]</tt></td> | <tt>$[?value(@..color) == "red"]</tt></td> | |||
<td align="left">well-typed</td> | <td align="left" colspan="1" rowspan="1">well-typed</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?value(@..color)]</tt></td> | <tt>$[?value(@..color)]</tt></td> | |||
<td align="left">not well-typed as <tt>ValueType</tt> may not be used in a test expression</td> | <td align="left" colspan="1" rowspan="1">not well-typed as <tt>V alueType</tt> may not be used in a test expression</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?bar(@.a)]</tt></td> | <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> | <td align="left" colspan="1" rowspan="1">well-typed for any func tion <tt>bar()</tt> with a parameter of any declared type and result type <tt>Lo gicalType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?bnl(@.*)]</tt></td> | <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 res ult type <tt>LogicalType</tt></td> | <td align="left" colspan="1" rowspan="1">well-typed for any func tion <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> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?blt(1==1)]</tt></td> | <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>Logic alType</tt></td> | <td align="left" colspan="1" rowspan="1">well-typed, where <tt>b lt()</tt> is a function with a parameter of declared type <tt>LogicalType</tt> a nd result type <tt>LogicalType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?blt(1)]</tt></td> | <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 expressio n</td> | <td align="left" colspan="1" rowspan="1">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> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[?bal(1)]</tt></td> | <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>Logical Type</tt></td> | <td align="left" colspan="1" rowspan="1">well-typed, where <tt>b al()</tt> is a function with a parameter of declared type <tt>ValueType</tt> and result type <tt>LogicalType</tt></td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="segments-details"> | <section anchor="segments-details" numbered="true" removeInRFC="false" toc | |||
<name>Segments</name> | ="include" pn="section-2.5"> | |||
<t>For each node in an input nodelist, | <name slugifiedName="name-segments-2">Segments</name> | |||
<t indent="0" pn="section-2.5-1">For each node in an input nodelist, | ||||
segments apply one or more selectors to the node and concatenate the | segments apply one or more selectors to the node and concatenate the | |||
results of each selector into per-input-node nodelists, which are then | results of each selector into per-input-node nodelists, which are then | |||
concatenated in the order of the input nodelist to form a single | concatenated in the order of the input nodelist to form a single | |||
segment result nodelist.</t> | segment result nodelist.</t> | |||
<t>It turns out that the more segments there are in a query, the greater the depth in the input value of the | <t indent="0" pn="section-2.5-2">It turns out that the more segments the re are in a query, the greater the depth in the input value of the | |||
nodes of the resultant nodelist:</t> | nodes of the resultant nodelist:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-2 | |||
<li>A query with N segments, where N >= 0, produces a nodelist | .5-3"> | |||
<li pn="section-2.5-3.1">A query with N segments, where N >= 0, pro | ||||
duces a nodelist | ||||
consisting of nodes at depth in the input value of N or greater.</li> | consisting of nodes at depth in the input value of N or greater.</li> | |||
<li>A query with N segments, where N >= 0, all of which are <xref t arget="child-segment">child segments</xref>, | <li pn="section-2.5-3.2">A query with N segments, where N >= 0, all of which are <xref target="child-segment" format="default" sectionFormat="of" d erivedContent="Section 2.5.1">child segments</xref>, | |||
produces a nodelist consisting of nodes precisely at depth N in the input value. </li> | produces a nodelist consisting of nodes precisely at depth N in the input value. </li> | |||
</ul> | </ul> | |||
<t>There are two kinds of segment: child segments and descendant segment | <t indent="0" pn="section-2.5-4">There are two kinds of segments: child | |||
s.</t> | segments and descendant segments.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="false" p | |||
n="section-2.5-5"> | ||||
segment = child-segment / descendant-segment | segment = child-segment / descendant-segment | |||
]]></sourcecode> | </sourcecode> | |||
<t>The syntax and semantics of each kind of segment are defined below.</ | <t indent="0" pn="section-2.5-6">The syntax and semantics of each kind o | |||
t> | f segment are defined below.</t> | |||
<section anchor="child-segment"> | <section anchor="child-segment" numbered="true" removeInRFC="false" toc= | |||
<name>Child Segment</name> | "include" pn="section-2.5.1"> | |||
<section anchor="syntax-4"> | <name slugifiedName="name-child-segment">Child Segment</name> | |||
<name>Syntax</name> | <section anchor="syntax-4" numbered="true" removeInRFC="false" toc="in | |||
<t>The child segment consists of a non-empty, comma-separated | clude" pn="section-2.5.1.1"> | |||
<name slugifiedName="name-syntax-8">Syntax</name> | ||||
<t indent="0" pn="section-2.5.1.1-1">The child segment consists of a | ||||
non-empty, comma-separated | ||||
sequence of selectors enclosed in square brackets.</t> | sequence of selectors enclosed in square brackets.</t> | |||
<t>Shorthand notations are also provided for when there is a single | <t indent="0" pn="section-2.5.1.1-2">Shorthand notations are also pr ovided for when there is a single | |||
wildcard or name selector.</t> | wildcard or name selector.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals e" pn="section-2.5.1.1-3"> | |||
child-segment = bracketed-selection / | child-segment = bracketed-selection / | |||
("." | ("." | |||
(wildcard-selector / | (wildcard-selector / | |||
member-name-shorthand)) | member-name-shorthand)) | |||
bracketed-selection = "[" S selector *(S "," S selector) S "]" | bracketed-selection = "[" S selector *(S "," S selector) S "]" | |||
member-name-shorthand = name-first *name-char | member-name-shorthand = name-first *name-char | |||
name-first = ALPHA / | name-first = ALPHA / | |||
"_" / | "_" / | |||
%x80-D7FF / ; skip surrogate code points | %x80-D7FF / | |||
; skip surrogate code points | ||||
%xE000-10FFFF | %xE000-10FFFF | |||
name-char = DIGIT / name-first | name-char = name-first / DIGIT | |||
DIGIT = %x30-39 ; 0-9 | DIGIT = %x30-39 ; 0-9 | |||
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z | ALPHA = %x41-5A / %x61-7A ; A-Z / a-z | |||
]]></sourcecode> | </sourcecode> | |||
<t><tt>.*</tt>, a <tt>child-segment</tt> directly built from a <tt>w | <t indent="0" pn="section-2.5.1.1-4"><tt>.*</tt>, a <tt>child-segmen | |||
ildcard-selector</tt>, is | t</tt> directly built from a <tt>wildcard-selector</tt>, is | |||
shorthand for <tt>[*]</tt>.</t> | shorthand for <tt>[*]</tt>.</t> | |||
<t><tt>.<member-name></tt>, a <tt>child-segment</tt> built fro m a | <t indent="0" pn="section-2.5.1.1-5"><tt>.<member-name></tt>, a <tt>child-segment</tt> built from a | |||
<tt>member-name-shorthand</tt>, is shorthand for <tt>['<member-name>']</t t>. | <tt>member-name-shorthand</tt>, is shorthand for <tt>['<member-name>']</t t>. | |||
Note: this can only be used with member names that are composed of certain | Note: This can only be used with member names that are composed of certain | |||
characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>. | characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>. | |||
Thus, for example, <tt>$.foo.bar</tt> is shorthand for <tt>$['foo']['bar']</tt> (but not for <tt>$['foo.bar']</tt>).</t> | Thus, for example, <tt>$.foo.bar</tt> is shorthand for <tt>$['foo']['bar']</tt> (but not for <tt>$['foo.bar']</tt>).</t> | |||
</section> | </section> | |||
<section anchor="semantics-6"> | <section anchor="semantics-6" numbered="true" removeInRFC="false" toc= | |||
<name>Semantics</name> | "include" pn="section-2.5.1.2"> | |||
<t>A child segment contains a sequence of selectors, each of which | <name slugifiedName="name-semantics-8">Semantics</name> | |||
<t indent="0" pn="section-2.5.1.2-1">A child segment contains a sequ | ||||
ence of selectors, each of which | ||||
selects zero or more children of the input value.</t> | selects zero or more children of the input value.</t> | |||
<t>Selectors of different kinds may be combined within a single chil | <t indent="0" pn="section-2.5.1.2-2">Selectors of different kinds ma | |||
d segment.</t> | y be combined within a single child segment.</t> | |||
<t>For each node in the input nodelist, | <t indent="0" pn="section-2.5.1.2-3">For each node in the input node | |||
list, | ||||
the resulting nodelist of a child segment is the concatenation of | the resulting nodelist of a child segment is the concatenation of | |||
the nodelists from each of its selectors in the order that the selectors | the nodelists from each of its selectors in the order that the selectors | |||
appear in the list. | appear in the list. | |||
Note: any node matched by more than one selector is kept | Note: Any node matched by more than one selector is kept | |||
as many times in the nodelist.</t> | as many times in the nodelist.</t> | |||
<t>Where a selector can produce a nodelist in more than one possible order, | <t indent="0" pn="section-2.5.1.2-4">Where a selector can produce a nodelist in more than one possible order, | |||
each occurrence of the selector in the child segment | each occurrence of the selector in the child segment | |||
may evaluate to produce a nodelist in a distinct order.</t> | may produce a nodelist in a distinct order.</t> | |||
<t>So a child segment drills down one more level into the structure | <t indent="0" pn="section-2.5.1.2-5">In summary, a child segment dri | |||
of the input value.</t> | lls down one more level into the structure of the input value.</t> | |||
</section> | </section> | |||
<section anchor="examples-7"> | <section anchor="examples-7" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.5.1.3"> | |||
<t>JSON:</t> | <name slugifiedName="name-examples-8">Examples</name> | |||
<sourcecode type="json"><![CDATA[ | <t indent="0" pn="section-2.5.1.3-1">JSON:</t> | |||
<sourcecode type="json" markers="false" pn="section-2.5.1.3-2"> | ||||
["a", "b", "c", "d", "e", "f", "g"] | ["a", "b", "c", "d", "e", "f", "g"] | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.5.1.3-3">Queries:</t> | |||
<table anchor="tbl-child-segment"> | <table anchor="tbl-child-segment" align="center" pn="table-15"> | |||
<name>Child segment examples</name> | <name slugifiedName="name-child-segment-examples">Child Segment Ex | |||
amples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0, 3]</tt></td> | <tt>$[0, 3]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"a"</tt> <br/> <tt>"d"</tt></td> | <tt>"a"</tt> <br/> <tt>"d"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0]</tt> <br/> <tt>$[3]</tt></td> | <tt>$[0]</tt> <br/> <tt>$[3]</tt></td> | |||
<td align="left">Indices</td> | <td align="left" colspan="1" rowspan="1">Indices</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0:2, 5]</tt></td> | <tt>$[0:2, 5]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"a"</tt> <br/> <tt>"b"</tt> <br/> <tt>"f"</tt></td> | <tt>"a"</tt> <br/> <tt>"b"</tt> <br/> <tt>"f"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[5]</tt></td> | <tt>$[0]</tt> <br/> <tt>$[1]</tt> <br/> <tt>$[5]</tt></td> | |||
<td align="left">Slice and index</td> | <td align="left" colspan="1" rowspan="1">Slice and index</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0, 0]</tt></td> | <tt>$[0, 0]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>"a"</tt> <br/> <tt>"a"</tt></td> | <tt>"a"</tt> <br/> <tt>"a"</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[0]</tt> <br/> <tt>$[0]</tt></td> | <tt>$[0]</tt> <br/> <tt>$[0]</tt></td> | |||
<td align="left">Duplicated entries</td> | <td align="left" colspan="1" rowspan="1">Duplicated entries</t d> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="descendant-segment"> | <section anchor="descendant-segment" numbered="true" removeInRFC="false" | |||
<name>Descendant Segment</name> | toc="include" pn="section-2.5.2"> | |||
<section anchor="syntax-5"> | <name slugifiedName="name-descendant-segment">Descendant Segment</name | |||
<name>Syntax</name> | > | |||
<t>The descendant segment consists of a double dot <tt>..</tt> | <section anchor="syntax-5" numbered="true" removeInRFC="false" toc="in | |||
clude" pn="section-2.5.2.1"> | ||||
<name slugifiedName="name-syntax-9">Syntax</name> | ||||
<t indent="0" pn="section-2.5.2.1-1">The descendant segment consists | ||||
of a double dot <tt>..</tt> | ||||
followed by a child segment (using bracket notation).</t> | followed by a child segment (using bracket notation).</t> | |||
<t>Shortand notations are also provided that correspond to the short | <t indent="0" pn="section-2.5.2.1-2">Shorthand notations are also pr | |||
hand forms of the child segment.</t> | ovided that correspond to the shorthand forms of the child segment.</t> | |||
<sourcecode type="abnf" name="jsonpath-collected.abnf"><![CDATA[ | <sourcecode type="abnf" name="jsonpath-collected.abnf" markers="fals | |||
e" pn="section-2.5.2.1-3"> | ||||
descendant-segment = ".." (bracketed-selection / | descendant-segment = ".." (bracketed-selection / | |||
wildcard-selector / | wildcard-selector / | |||
member-name-shorthand) | member-name-shorthand) | |||
]]></sourcecode> | </sourcecode> | |||
<t><tt>..*</tt>, the <tt>descendant-segment</tt> directly built from | <t indent="0" pn="section-2.5.2.1-4"><tt>..*</tt>, the <tt>descendan | |||
a | t-segment</tt> directly built from a | |||
<tt>wildcard-selector</tt>, is shorthand for <tt>..[*]</tt>.</t> | <tt>wildcard-selector</tt>, is shorthand for <tt>..[*]</tt>.</t> | |||
<t><tt>..<member-name></tt>, a <tt>descendant-segment</tt> bui | <t indent="0" pn="section-2.5.2.1-5"><tt>..<member-name></tt>, | |||
lt from a | a <tt>descendant-segment</tt> built from a | |||
<tt>member-name-shorthand</tt>, is shorthand for <tt>..['<member-name>']</ | <tt>member-name-shorthand</tt>, is shorthand for <tt>..['<member-name>']< | |||
tt>. | /tt>. | |||
Note: as with the similar shorthand of a <tt>child-segment</tt>, this can | Note: As with the similar shorthand of a <tt>child-segment</tt>, this can | |||
only be used with member names that are composed of certain | only be used with member names that are composed of certain | |||
characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>.</t> | characters, as specified in the ABNF rule <tt>member-name-shorthand</tt>.</t> | |||
<t>Note: <tt>..</tt> on its own is not a valid segment.</t> | <t indent="0" pn="section-2.5.2.1-6">Note: On its own, <tt>..</tt> i s not a valid segment.</t> | |||
</section> | </section> | |||
<section anchor="semantics-7"> | <section anchor="semantics-7" numbered="true" removeInRFC="false" toc= | |||
<name>Semantics</name> | "include" pn="section-2.5.2.2"> | |||
<t>A descendant segment produces zero or more descendants of an inpu | <name slugifiedName="name-semantics-9">Semantics</name> | |||
t value.</t> | <t indent="0" pn="section-2.5.2.2-1">A descendant segment produces z | |||
<t>For each node in the input nodelist, | ero or more descendants of an input value.</t> | |||
<t indent="0" pn="section-2.5.2.2-2">For each node in the input node | ||||
list, | ||||
a descendant selector visits the input node and each of | a descendant selector visits the input node and each of | |||
its descendants such that:</t> | its descendants such that:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="secti | |||
<li>nodes of any array are visited in array order, and</li> | on-2.5.2.2-3"> | |||
<li>nodes are visited before their descendants.</li> | <li pn="section-2.5.2.2-3.1">nodes of any array are visited in arr | |||
ay order, and</li> | ||||
<li pn="section-2.5.2.2-3.2">nodes are visited before their descen | ||||
dants.</li> | ||||
</ul> | </ul> | |||
<t>The order in which the children of an object are visited is not s tipulated, since | <t indent="0" pn="section-2.5.2.2-4">The order in which the children of an object are visited is not stipulated, since | |||
JSON objects are unordered.</t> | JSON objects are unordered.</t> | |||
<t>Suppose the descendant segment is of the form <tt>..[<selector | <t indent="0" pn="section-2.5.2.2-5">Suppose the descendant segment | |||
s>]</tt> (after converting any shorthand | is of the form <tt>..[<selectors>]</tt> (after converting any shorthand | |||
form to bracket notation) | form to bracket notation), | |||
and the nodes, in the order visited, are <tt>D1</tt>, ..., <tt>Dn</tt> (where <t t>n >= 1</tt>). | and the nodes, in the order visited, are <tt>D1</tt>, ..., <tt>Dn</tt> (where <t t>n >= 1</tt>). | |||
Note: <tt>D1</tt> is the input value.</t> | Note: <tt>D1</tt> is the input value.</t> | |||
<t>For each <tt>i</tt> such that <tt>1 <= i <= n</tt>, the nod elist <tt>Ri</tt> is defined to be a result of applying | <t indent="0" pn="section-2.5.2.2-6">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> | the child segment <tt>[<selectors>]</tt> to the node <tt>Di</tt>.</t> | |||
<t>For each node in the input nodelist, | <t indent="0" pn="section-2.5.2.2-7">For each node in the input node list, | |||
the result of the descendant segment is the concatenation of <tt>R1</tt>, | the result of the descendant segment is the concatenation of <tt>R1</tt>, | |||
..., <tt>Rn</tt> (in that order). | ..., <tt>Rn</tt> (in that order). | |||
These results are then concatenated in input nodelist order to form | These results are then concatenated in input nodelist order to form | |||
the result of the segment.</t> | the result of the segment.</t> | |||
<t>So a descendant segment drills down one or more levels into the s tructure of each input value.</t> | <t indent="0" pn="section-2.5.2.2-8">In summary, a descendant segmen t drills down one or more levels into the structure of each input value.</t> | |||
</section> | </section> | |||
<section anchor="examples-8"> | <section anchor="examples-8" numbered="true" removeInRFC="false" toc=" | |||
<name>Examples</name> | include" pn="section-2.5.2.3"> | |||
<t>JSON:</t> | <name slugifiedName="name-examples-9">Examples</name> | |||
<sourcecode type="json"><![CDATA[ | <t indent="0" pn="section-2.5.2.3-1">JSON:</t> | |||
<sourcecode type="json" markers="false" pn="section-2.5.2.3-2"> | ||||
{ | { | |||
"o": {"j": 1, "k": 2}, | "o": {"j": 1, "k": 2}, | |||
"a": [5, 3, [{"j": 4}, {"k": 6}]] | "a": [5, 3, [{"j": 4}, {"k": 6}]] | |||
} | } | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.5.2.3-3">Queries:</t> | |||
<t>(Note that the fourth example can be expressed in two equivalent | <t indent="0" pn="section-2.5.2.3-4">(Note that the fourth example c | |||
queries, shown here in one table row instead of two almost identical rows.)</t> | an be expressed in two equivalent | |||
<table anchor="tbl-descendant-segment"> | queries, shown in <xref target="tbl-descendant-segment" format="default" section | |||
<name>Descendant segment examples</name> | Format="of" derivedContent="Table 16"/> in one table row instead of two almost-i | |||
dentical rows.)</t> | ||||
<table anchor="tbl-descendant-segment" align="center" pn="table-16"> | ||||
<name slugifiedName="name-descendant-segment-examples">Descendant | ||||
Segment Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$..j</tt></td> | <tt>$..j</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt> <br/> <tt>4</tt></td> | <tt>1</tt> <br/> <tt>4</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j']</tt> <br/> <tt>$['a'][2][0]['j']</tt></td> | <tt>$['o']['j']</tt> <br/> <tt>$['a'][2][0]['j']</tt></td> | |||
<td align="left">Object values</td> | <td align="left" colspan="1" rowspan="1">Object values</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$..j</tt></td> | <tt>$..j</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>4</tt> <br/> <tt>1</tt></td> | <tt>4</tt> <br/> <tt>1</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][2][0]['j']</tt> <br/> <tt>$['o']['j']</tt></td> | <tt>$['a'][2][0]['j']</tt> <br/> <tt>$['o']['j']</tt></td> | |||
<td align="left">Alternative result</td> | <td align="left" colspan="1" rowspan="1">Alternative result</t d> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$..[0]</tt></td> | <tt>$..[0]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>5</tt> <br/> <tt>{"j": 4}</tt></td> | <tt>5</tt> <br/> <tt>{"j": 4}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][0]</tt> <br/> <tt>$['a'][2][0]</tt></td> | <tt>$['a'][0]</tt> <br/> <tt>$['a'][2][0]</tt></td> | |||
<td align="left">Array values</td> | <td align="left" colspan="1" rowspan="1">Array values</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$..[*]</tt> <br/>or<br/> <tt>$..*</tt></td> | <tt>$..[*]</tt> <br/>or<br/> <tt>$..*</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<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> <b r/> <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> | <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> <b r/> <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"> | <td align="center" colspan="1" rowspan="1"> | |||
<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]</t t> <br/> <tt>$['a'][2][0]['j']</tt> <br/> <tt>$['a'][2][1]['k']</tt></td> | <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]</t t> <br/> <tt>$['a'][2][0]['j']</tt> <br/> <tt>$['a'][2][1]['k']</tt></td> | |||
<td align="left">All values</td> | <td align="left" colspan="1" rowspan="1">All values</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$..o</tt></td> | <tt>$..o</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>{"j": 1, "k": 2}</tt></td> | <tt>{"j": 1, "k": 2}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']</tt></td> | <tt>$['o']</tt></td> | |||
<td align="left">Input value is visited</td> | <td align="left" colspan="1" rowspan="1">Input value is visite d</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.o..[*, *]</tt></td> | <tt>$.o..[*, *]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt ></td> | <tt>1</tt> <br/> <tt>2</tt> <br/> <tt>2</tt> <br/> <tt>1</tt ></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['o']['j']</tt> <br/> <tt>$['o']['k']</tt> <br/> <tt>$[ 'o']['k']</tt> <br/> <tt>$['o']['j']</tt></td> | <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> | <td align="left" colspan="1" rowspan="1">Non-deterministic ord ering</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a..[0, 1]</tt></td> | <tt>$.a..[0, 1]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>5</tt> <br/> <tt>3</tt> <br/> <tt>{"j": 4}</tt> <br/> <t t>{"k": 6}</tt></td> | <tt>5</tt> <br/> <tt>3</tt> <br/> <tt>{"j": 4}</tt> <br/> <t t>{"k": 6}</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt> <br/> <tt>$['a'] [2][0]</tt> <br/> <tt>$['a'][2][1]</tt></td> | <tt>$['a'][0]</tt> <br/> <tt>$['a'][1]</tt> <br/> <tt>$['a'] [2][0]</tt> <br/> <tt>$['a'][2][1]</tt></td> | |||
<td align="left">Multiple segments</td> | <td align="left" colspan="1" rowspan="1">Multiple segments</td > | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>Note: the ordering of the results for the <tt>$..[*]</tt> and <tt | <t indent="0" pn="section-2.5.2.3-6">Note: The ordering of the resul | |||
>$..*</tt> examples above is not guaranteed, except that:</t> | ts for the <tt>$..[*]</tt> and <tt>$..*</tt> examples above is not guaranteed, e | |||
<ul spacing="normal"> | xcept that:</t> | |||
<li> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="secti | |||
on-2.5.2.3-7"> | ||||
<li pn="section-2.5.2.3-7.1"> | ||||
<tt>{"j": 1, "k": 2}</tt> must appear before <tt>1</tt> and <tt> 2</tt>,</li> | <tt>{"j": 1, "k": 2}</tt> must appear before <tt>1</tt> and <tt> 2</tt>,</li> | |||
<li> | <li pn="section-2.5.2.3-7.2"> | |||
<tt>[5, 3, [{"j": 4}, {"k": 6}]]</tt> must appear before <tt>5</ tt>, <tt>3</tt>, and <tt>[{"j": 4}, {"k": 6}]</tt>,</li> | <tt>[5, 3, [{"j": 4}, {"k": 6}]]</tt> must appear before <tt>5</ tt>, <tt>3</tt>, and <tt>[{"j": 4}, {"k": 6}]</tt>,</li> | |||
<li> | <li pn="section-2.5.2.3-7.3"> | |||
<tt>5</tt> must appear before <tt>3</tt> which must appear befor | <tt>5</tt> must appear before <tt>3</tt>, which must appear befo | |||
e <tt>[{"j": 4}, {"k": 6}]</tt>,</li> | re <tt>[{"j": 4}, {"k": 6}]</tt>,</li> | |||
<li> | <li pn="section-2.5.2.3-7.4"> | |||
<tt>5</tt> and <tt>3</tt> must appear before <tt>{"j": 4}</tt>, | <tt>5</tt> and <tt>3</tt> must appear before <tt>{"j": 4}</tt>, | |||
<tt>4</tt>, <tt>, {"k": 6}</tt>, and <tt>6</tt>,</li> | <tt>4</tt>, <tt>{"k": 6}</tt>, and <tt>6</tt>,</li> | |||
<li> | <li pn="section-2.5.2.3-7.5"> | |||
<tt>[{"j": 4}, {"k": 6}]</tt> must appear before <tt>{"j": 4}</t t> and <tt>{"k": 6}</tt>,</li> | <tt>[{"j": 4}, {"k": 6}]</tt> must appear before <tt>{"j": 4}</t t> and <tt>{"k": 6}</tt>,</li> | |||
<li> | <li pn="section-2.5.2.3-7.6"> | |||
<tt>{"j": 4}</tt> must appear before <tt>{"k": 6}</tt>,</li> | <tt>{"j": 4}</tt> must appear before <tt>{"k": 6}</tt>,</li> | |||
<li> | <li pn="section-2.5.2.3-7.7"> | |||
<tt>{"k": 6}</tt> must appear before <tt>4</tt>, and</li> | <tt>{"k": 6}</tt> must appear before <tt>4</tt>, and</li> | |||
<li> | <li pn="section-2.5.2.3-7.8"> | |||
<tt>4</tt> must appear before <tt>6</tt>.</li> | <tt>4</tt> must appear before <tt>6</tt>.</li> | |||
</ul> | </ul> | |||
<t>The example above with the query <tt>$.o..[*, *]</tt> shows that a selector may produce nodelists in distinct orders | <t indent="0" pn="section-2.5.2.3-8">The example above with the quer y <tt>$.o..[*, *]</tt> shows that a selector may produce nodelists in distinct o rders | |||
each time it appears in the descendant segment.</t> | each time it appears in the descendant segment.</t> | |||
<t>The example above with the query <tt>$.a..[0, 1]</tt> shows that the child segment <tt>[0, 1]</tt> is applied to each node | <t indent="0" pn="section-2.5.2.3-9">The example above with the quer y <tt>$.a..[0, 1]</tt> shows that the child segment <tt>[0, 1]</tt> is applied t o each node | |||
in turn (rather than the nodes being visited once per selector, which is the cas e for some JSONPath implementations | in turn (rather than the nodes being visited once per selector, which is the cas e for some JSONPath implementations | |||
that do not conform to this specification).</t> | that do not conform to this specification).</t> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="null-semantics"> | <section anchor="null-semantics" numbered="true" removeInRFC="false" toc=" | |||
<name>Semantics of <tt>null</tt></name> | include" pn="section-2.6"> | |||
<t>Note: JSON <tt>null</tt> is treated the same as any other JSON value: | <name slugifiedName="name-semantics-of-null">Semantics of <tt>null</tt>< | |||
it is not taken to mean "undefined" or "missing".</t> | /name> | |||
<section anchor="examples-9"> | <t indent="0" pn="section-2.6-1">Note: JSON <tt>null</tt> is treated the | |||
<name>Examples</name> | same as any other JSON value, i.e., it is not taken to mean "undefined" or "mis | |||
<t>JSON:</t> | sing".</t> | |||
<sourcecode type="json"><![CDATA[ | <section anchor="examples-9" numbered="true" removeInRFC="false" toc="in | |||
clude" pn="section-2.6.1"> | ||||
<name slugifiedName="name-examples-10">Examples</name> | ||||
<t indent="0" pn="section-2.6.1-1">JSON:</t> | ||||
<sourcecode type="json" markers="false" pn="section-2.6.1-2"> | ||||
{"a": null, "b": [null], "c": [{}], "null": 1} | {"a": null, "b": [null], "c": [{}], "null": 1} | |||
]]></sourcecode> | </sourcecode> | |||
<t>Queries:</t> | <t indent="0" pn="section-2.6.1-3">Queries:</t> | |||
<table anchor="tbl-null-examples"> | <table anchor="tbl-null-examples" align="center" pn="table-17"> | |||
<name>Examples involving (or not involving) null</name> | <name slugifiedName="name-examples-involving-or-not-i">Examples Invo | |||
lving (or Not Involving) <tt>null</tt></name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Query</th> | <th align="center" colspan="1" rowspan="1">Query</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
<th align="center">Result Paths</th> | <th align="center" colspan="1" rowspan="1">Result Paths</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a</tt></td> | <tt>$.a</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt></td> | <tt>null</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a']</tt></td> | <tt>$['a']</tt></td> | |||
<td align="left">Object value</td> | <td align="left" colspan="1" rowspan="1">Object value</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a[0]</tt></td> | <tt>$.a[0]</tt></td> | |||
<td align="left"> </td> | <td align="left" colspan="1" rowspan="1"> </td> | |||
<td align="center"> </td> | <td align="center" colspan="1" rowspan="1"> </td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt> used as array</td> | <tt>null</tt> used as array</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a.d</tt></td> | <tt>$.a.d</tt></td> | |||
<td align="left"> </td> | <td align="left" colspan="1" rowspan="1"> </td> | |||
<td align="center"> </td> | <td align="center" colspan="1" rowspan="1"> </td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt> used as object</td> | <tt>null</tt> used as object</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.b[0]</tt></td> | <tt>$.b[0]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt></td> | <tt>null</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['b'][0]</tt></td> | <tt>$['b'][0]</tt></td> | |||
<td align="left">Array value</td> | <td align="left" colspan="1" rowspan="1">Array value</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.b[*]</tt></td> | <tt>$.b[*]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt></td> | <tt>null</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['b'][0]</tt></td> | <tt>$['b'][0]</tt></td> | |||
<td align="left">Array value</td> | <td align="left" colspan="1" rowspan="1">Array value</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.b[?@]</tt></td> | <tt>$.b[?@]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt></td> | <tt>null</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['b'][0]</tt></td> | <tt>$['b'][0]</tt></td> | |||
<td align="left">Existence</td> | <td align="left" colspan="1" rowspan="1">Existence</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.b[?@==null]</tt></td> | <tt>$.b[?@==null]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>null</tt></td> | <tt>null</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['b'][0]</tt></td> | <tt>$['b'][0]</tt></td> | |||
<td align="left">Comparison</td> | <td align="left" colspan="1" rowspan="1">Comparison</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.c[?@.d==null]</tt></td> | <tt>$.c[?@.d==null]</tt></td> | |||
<td align="left"> </td> | <td align="left" colspan="1" rowspan="1"> </td> | |||
<td align="center"> </td> | <td align="center" colspan="1" rowspan="1"> </td> | |||
<td align="left">Comparison with "missing" value</td> | <td align="left" colspan="1" rowspan="1">Comparison with "missin | |||
g" value</td> | ||||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.null</tt></td> | <tt>$.null</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>1</tt></td> | <tt>1</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['null']</tt></td> | <tt>$['null']</tt></td> | |||
<td align="left">Not JSON null at all, just a member name string </td> | <td align="left" colspan="1" rowspan="1">Not JSON <tt>null</tt> at all, just a member name string</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="normalized-paths"> | <section anchor="normalized-paths" numbered="true" removeInRFC="false" toc | |||
<name>Normalized Paths</name> | ="include" pn="section-2.7"> | |||
<t>A Normalized Path is a unique representation of the location of a nod | <name slugifiedName="name-normalized-paths">Normalized Paths</name> | |||
e in a value which | <t indent="0" pn="section-2.7-1">A Normalized Path is a unique represent | |||
ation of the location of a node in a value that | ||||
uniquely identifies the node in the value. | uniquely identifies the node in the value. | |||
Specifically, a Normalized Path is a JSONPath query with restricted syntax (defi ned below), | Specifically, a Normalized Path is a JSONPath query with restricted syntax (defi ned below), | |||
e.g., <tt>$['book'][3]</tt>, which when applied to the value results in a nodeli st consisting | e.g., <tt>$['book'][3]</tt>, which when applied to the value, results in a nodel ist consisting | |||
of just the node identified by the Normalized Path. | of just the node identified by the Normalized Path. | |||
Note: a Normalized Path represents the identity of a node <em>in a specific valu e</em>. | Note: A Normalized Path represents the identity of a node <em>in a specific valu e</em>. | |||
There is precisely one Normalized Path identifying any particular node in a valu e.</t> | There is precisely one Normalized Path identifying any particular node in a valu e.</t> | |||
<t>A nodelist may be represented compactly in JSON as an array of string s, where the strings are | <t indent="0" pn="section-2.7-2">A nodelist may be represented compactly in JSON as an array of strings, where the strings are | |||
Normalized Paths.</t> | Normalized Paths.</t> | |||
<t>Normalized Paths provide a predictable format that simplifies testing and post-processing | <t indent="0" pn="section-2.7-3">Normalized Paths provide a predictable format that simplifies testing and post-processing | |||
of nodelists, e.g., to remove duplicate nodes. | of nodelists, e.g., to remove duplicate nodes. | |||
Normalized Paths are used in this document as result paths in examples.</t> | Normalized Paths are used in this document as result paths in examples.</t> | |||
<t>Normalized Paths use the canonical bracket notation, rather than dot | <t indent="0" pn="section-2.7-4">Normalized Paths use the canonical brac | |||
notation.</t> | ket notation, rather than dot notation.</t> | |||
<t>Single quotes are used in Normalized Paths to delimit string member n | <t indent="0" pn="section-2.7-5">Single quotes are used in Normalized Pa | |||
ames. This reduces the | ths to delimit string member names. This reduces the | |||
number of characters that need escaping when Normalized Paths appear in double q | number of characters that need escaping when Normalized Paths appear in | |||
uote-delimited | strings delimited by double quotes, e.g., in JSON texts.</t> | |||
strings, e.g., in JSON texts.</t> | <t indent="0" pn="section-2.7-6">Certain characters are escaped in Norma | |||
<t>Certain characters are escaped in Normalized Paths, in one and only o | lized Paths in one and only one way; all other | |||
ne way; all other | characters are unescaped.</t> | |||
characters are unescaped.</t> | <aside pn="section-2.7-7"> | |||
<t>Note: Normalized Paths are singular queries, but not all singular que | <t indent="0" pn="section-2.7-7.1">Note: Normalized Paths are singular | |||
ries are Normalized Paths. | queries, but not all singular queries are Normalized Paths. | |||
For example, <tt>$[-3]</tt> is a singular query, but is not a Normalized Path. | For example, <tt>$[-3]</tt> is a singular query but is not a Normalized Path. | |||
The Normalized Path equivalent to <tt>$[-3]</tt> would have an index equal to th e array length minus <tt>3</tt>. | The Normalized Path equivalent to <tt>$[-3]</tt> would have an index equal to th e array length minus <tt>3</tt>. | |||
(The array length must be at least <tt>3</tt> if <tt>$[-3]</tt> is to identify a | (The array length must be at least <tt>3</tt> if <tt>$[-3]</tt> is to ide | |||
node.)</t> | ntify a node.)</t> | |||
<sourcecode type="abnf" name="normalized-path-collected.abnf"><![CDATA[ | </aside> | |||
<sourcecode type="abnf" name="normalized-path-collected.abnf" markers="f | ||||
alse" pn="section-2.7-8"> | ||||
normalized-path = root-identifier *(normal-index-segment) | normalized-path = root-identifier *(normal-index-segment) | |||
normal-index-segment = "[" normal-selector "]" | normal-index-segment = "[" normal-selector "]" | |||
normal-selector = normal-name-selector / normal-index-selector | normal-selector = normal-name-selector / normal-index-selector | |||
normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' | normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' | |||
normal-single-quoted = normal-unescaped / | normal-single-quoted = normal-unescaped / | |||
ESC normal-escapable | ESC normal-escapable | |||
normal-unescaped = ; omit %x0-1F control codes | normal-unescaped = ; omit %x0-1F control codes | |||
%x20-26 / | %x20-26 / | |||
; omit 0x27 ' | ; omit 0x27 ' | |||
%x28-5B / | %x28-5B / | |||
; omit 0x5C \ | ; omit 0x5C \ | |||
%x5D-D7FF / ; skip surrogate code points | %x5D-D7FF / | |||
; skip surrogate code points | ||||
%xE000-10FFFF | %xE000-10FFFF | |||
normal-escapable = %x62 / ; b BS backspace U+0008 | normal-escapable = %x62 / ; b BS backspace U+0008 | |||
%x66 / ; f FF form feed U+000C | %x66 / ; f FF form feed U+000C | |||
%x6E / ; n LF line feed U+000A | %x6E / ; n LF line feed U+000A | |||
%x72 / ; r CR carriage return U+000D | %x72 / ; r CR carriage return U+000D | |||
%x74 / ; t HT horizontal tab U+0009 | %x74 / ; t HT horizontal tab U+0009 | |||
"'" / ; ' apostrophe U+0027 | "'" / ; ' apostrophe U+0027 | |||
"\" / ; \ backslash (reverse solidus) U+005C | "\" / ; \ backslash (reverse solidus) U+005C | |||
(%x75 normal-hexchar) | (%x75 normal-hexchar) | |||
; certain values u00xx U+00XX | ; certain values u00xx U+00XX | |||
normal-hexchar = "0" "0" | normal-hexchar = "0" "0" | |||
( | ( | |||
("0" %x30-37) / ; "00"-"07" | ("0" %x30-37) / ; "00"-"07" | |||
; omit U+0008-U+000A BS HT LF | ; omit U+0008-U+000A BS HT LF | |||
("0" %x62) / ; "0b" | ("0" %x62) / ; "0b" | |||
; omit U+000C-U+000D FF CR | ; omit U+000C-U+000D FF CR | |||
("0" %x65-66) / ; "0e"-"0f" | ("0" %x65-66) / ; "0e"-"0f" | |||
("1" normal-HEXDIG) | ("1" normal-HEXDIG) | |||
) | ) | |||
normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" | normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" | |||
normal-index-selector = "0" / (DIGIT1 *DIGIT) | normal-index-selector = "0" / (DIGIT1 *DIGIT) | |||
; non-negative decimal integer | ; non-negative decimal integer | |||
]]></sourcecode> | </sourcecode> | |||
<t>Since there can only be one Normalized Path identifying a given node, | <t indent="0" pn="section-2.7-9">Since there can only be one Normalized | |||
the syntax | Path identifying a given node, the syntax | |||
stipulates which characters are escaped and which are not. | stipulates which characters are escaped and which are not. | |||
So the definition of <tt>normal-hexchar</tt> is designed for hex escaping of cha racters | So the definition of <tt>normal-hexchar</tt> is designed for hex escaping of cha racters | |||
which are not straightforwardly printable, for example U+000B LINE TABULATION, b ut | that are not straightforwardly printable, for example, U+000B LINE TABULATION, b ut | |||
for which no standard JSON escape, such as <tt>\n</tt>, is available.</t> | for which no standard JSON escape, such as <tt>\n</tt>, is available.</t> | |||
<section anchor="examples-10"> | <section anchor="examples-10" numbered="true" removeInRFC="false" toc="i | |||
<name>Examples</name> | nclude" pn="section-2.7.1"> | |||
<table anchor="tbl-normalized-path-examples"> | <name slugifiedName="name-examples-11">Examples</name> | |||
<name>Normalized Path examples</name> | <table anchor="tbl-normalized-path-examples" align="center" pn="table- | |||
18"> | ||||
<name slugifiedName="name-normalized-path-examples">Normalized Path | ||||
Examples</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="center">Path</th> | <th align="center" colspan="1" rowspan="1">Path</th> | |||
<th align="center">Normalized Path</th> | <th align="center" colspan="1" rowspan="1">Normalized Path</th> | |||
<th align="left">Comment</th> | <th align="left" colspan="1" rowspan="1">Comment</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a</tt></td> | <tt>$.a</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a']</tt></td> | <tt>$['a']</tt></td> | |||
<td align="left">Object value</td> | <td align="left" colspan="1" rowspan="1">Object value</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1]</tt></td> | <tt>$[1]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[1]</tt></td> | <tt>$[1]</tt></td> | |||
<td align="left">Array index</td> | <td align="left" colspan="1" rowspan="1">Array index</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[-3]</tt></td> | <tt>$[-3]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$[2]</tt></td> | <tt>$[2]</tt></td> | |||
<td align="left">Negative array index for an array of length 5</ td> | <td align="left" colspan="1" rowspan="1">Negative array index fo r an array of length 5</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$.a.b[1:2]</tt></td> | <tt>$.a.b[1:2]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a']['b'][1]</tt></td> | <tt>$['a']['b'][1]</tt></td> | |||
<td align="left">Nested structure</td> | <td align="left" colspan="1" rowspan="1">Nested structure</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$["\u000B"]</tt></td> | <tt>$["\u000B"]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['\u000b']</tt></td> | <tt>$['\u000b']</tt></td> | |||
<td align="left">Unicode escape</td> | <td align="left" colspan="1" rowspan="1">Unicode escape</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$["\u0061"]</tt></td> | <tt>$["\u0061"]</tt></td> | |||
<td align="center"> | <td align="center" colspan="1" rowspan="1"> | |||
<tt>$['a']</tt></td> | <tt>$['a']</tt></td> | |||
<td align="left">Unicode character</td> | <td align="left" colspan="1" rowspan="1">Unicode character</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="IANA"> | <section anchor="IANA" numbered="true" removeInRFC="false" toc="include" pn= | |||
<name>IANA Considerations</name> | "section-3"> | |||
<t><cref anchor="replace-xxxx">RFC Ed.: throughout this section, please re | <name slugifiedName="name-iana-considerations">IANA Considerations</name> | |||
place | <section anchor="registration-of-media-type-applicationjsonpath" numbered= | |||
RFCXXXX with the RFC number of this specification and remove this | "true" removeInRFC="false" toc="include" pn="section-3.1"> | |||
note.</cref></t> | <name slugifiedName="name-registration-of-media-type-">Registration of M | |||
<section anchor="registration-of-media-type-applicationjsonpath"> | edia Type application/jsonpath</name> | |||
<name>Registration of Media Type application/jsonpath</name> | <t indent="0" pn="section-3.1-1">IANA has registered the following media | |||
<t>IANA is requested to register the following media type <xref target=" | type <xref target="RFC6838" format="default" sectionFormat="of" derivedContent= | |||
RFC6838"/>:</t> | "RFC6838"/>:</t> | |||
<dl> | <dl indent="3" newline="false" spacing="normal" pn="section-3.1-2"> | |||
<dt>Type name:</dt> | <dt pn="section-3.1-2.1">Type name:</dt> | |||
<dd> | <dd pn="section-3.1-2.2"> | |||
<t>application</t> | <t indent="0" pn="section-3.1-2.2.1">application</t> | |||
</dd> | </dd> | |||
<dt>Subtype name:</dt> | <dt pn="section-3.1-2.3">Subtype name:</dt> | |||
<dd> | <dd pn="section-3.1-2.4"> | |||
<t>jsonpath</t> | <t indent="0" pn="section-3.1-2.4.1">jsonpath</t> | |||
</dd> | </dd> | |||
<dt>Required parameters:</dt> | <dt pn="section-3.1-2.5">Required parameters:</dt> | |||
<dd> | <dd pn="section-3.1-2.6"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.6.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>Optional parameters:</dt> | <dt pn="section-3.1-2.7">Optional parameters:</dt> | |||
<dd> | <dd pn="section-3.1-2.8"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.8.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>Encoding considerations:</dt> | <dt pn="section-3.1-2.9">Encoding considerations:</dt> | |||
<dd> | <dd pn="section-3.1-2.10"> | |||
<t>binary (UTF-8)</t> | <t indent="0" pn="section-3.1-2.10.1">binary (UTF-8)</t> | |||
</dd> | </dd> | |||
<dt>Security considerations:</dt> | <dt pn="section-3.1-2.11">Security considerations:</dt> | |||
<dd> | <dd pn="section-3.1-2.12"> | |||
<t>See the Security Considerations section of RFCXXXX.</t> | <t indent="0" pn="section-3.1-2.12.1">See the Security Consideration | |||
s section of RFC 9535.</t> | ||||
</dd> | </dd> | |||
<dt>Interoperability considerations:</dt> | <dt pn="section-3.1-2.13">Interoperability considerations:</dt> | |||
<dd> | <dd pn="section-3.1-2.14"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.14.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>Published specification:</dt> | <dt pn="section-3.1-2.15">Published specification:</dt> | |||
<dd> | <dd pn="section-3.1-2.16"> | |||
<t>RFCXXXX</t> | <t indent="0" pn="section-3.1-2.16.1">RFC 9535</t> | |||
</dd> | </dd> | |||
<dt>Applications that use this media type:</dt> | <dt pn="section-3.1-2.17">Applications that use this media type:</dt> | |||
<dd> | <dd pn="section-3.1-2.18"> | |||
<t>Applications that need to convey queries in JSON data</t> | <t indent="0" pn="section-3.1-2.18.1">Applications that need to conv | |||
ey queries in JSON data</t> | ||||
</dd> | </dd> | |||
<dt>Fragment identifier considerations:</dt> | <dt pn="section-3.1-2.19">Fragment identifier considerations:</dt> | |||
<dd> | <dd pn="section-3.1-2.20"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.20.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>Additional information:</dt> | <dt pn="section-3.1-2.21">Additional information:</dt> | |||
<dd> | <dd pn="section-3.1-2.22"> | |||
<dl> | <t indent="0" pn="section-3.1-2.22.1"><br/></t> | |||
<dt>Deprecated alias names for this type:</dt> | <dl spacing="compact" indent="3" newline="false" pn="section-3.1-2.2 | |||
<dd> | 2.2"> | |||
<t>N/A</t> | <dt pn="section-3.1-2.22.2.1">Deprecated alias names for this type | |||
:</dt> | ||||
<dd pn="section-3.1-2.22.2.2"> | ||||
<t indent="0" pn="section-3.1-2.22.2.2.1">N/A</t> | ||||
</dd> | </dd> | |||
<dt>Magic number(s):</dt> | <dt pn="section-3.1-2.22.2.3">Magic number(s):</dt> | |||
<dd> | <dd pn="section-3.1-2.22.2.4"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.22.2.4.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>File extension(s):</dt> | <dt pn="section-3.1-2.22.2.5">File extension(s):</dt> | |||
<dd> | <dd pn="section-3.1-2.22.2.6"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.22.2.6.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>Macintosh file type code(s):</dt> | <dt pn="section-3.1-2.22.2.7">Macintosh file type code(s):</dt> | |||
<dd> | <dd pn="section-3.1-2.22.2.8"> | |||
<t>N/A</t> | <t indent="0" pn="section-3.1-2.22.2.8.1">N/A</t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
</dd> | </dd> | |||
</dl> | <dt pn="section-3.1-2.23">Person & email address to contact for fu | |||
<t>Person & email address to contact for further information: | rther information:</dt> | |||
iesg@ietf.org</t> | <dd pn="section-3.1-2.24">iesg@ietf.org</dd> | |||
<dl> | <dt pn="section-3.1-2.25">Intended usage:</dt> | |||
<dt>Intended usage:</dt> | <dd pn="section-3.1-2.26"> | |||
<dd> | <t indent="0" pn="section-3.1-2.26.1">COMMON</t> | |||
<t>COMMON</t> | ||||
</dd> | ||||
<dt>Restrictions on usage:</dt> | ||||
<dd> | ||||
<t>N/A</t> | ||||
</dd> | </dd> | |||
<dt>Author:</dt> | <dt pn="section-3.1-2.27">Restrictions on usage:</dt> | |||
<dd> | <dd pn="section-3.1-2.28"> | |||
<t>JSONPath WG</t> | <t indent="0" pn="section-3.1-2.28.1">N/A</t> | |||
</dd> | </dd> | |||
<dt>Change controller:</dt> | <dt pn="section-3.1-2.29">Author:</dt> | |||
<dd> | <dd pn="section-3.1-2.30"> | |||
<t>IETF</t> | <t indent="0" pn="section-3.1-2.30.1">JSONPath WG</t> | |||
</dd> | </dd> | |||
<dt>Provisional registration? (standards tree only):</dt> | <dt pn="section-3.1-2.31">Change controller:</dt> | |||
<dd> | <dd pn="section-3.1-2.32"> | |||
<t>no</t> | <t indent="0" pn="section-3.1-2.32.1">IETF</t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
</section> | </section> | |||
<section anchor="iana-fnex"> | <section anchor="iana-fnex" numbered="true" removeInRFC="false" toc="inclu | |||
<name>Function Extensions</name> | de" pn="section-3.2"> | |||
<t>This specification defines a new "Function Extensions sub-registry" i | <name slugifiedName="name-function-extensions-subregi">Function Extensio | |||
n | ns Subregistry</name> | |||
a new "JSONPath Parameters registry", with the policy "expert review" | <t indent="0" pn="section-3.2-1">Per this specification, IANA has create | |||
(<xref section="4.5" sectionFormat="of" target="BCP26"/>).</t> | d a new "Function Extensions" subregistry in | |||
<t anchor="de-instructions">The experts are instructed to be frugal in t | a new "JSONPath" registry. The "Function Extensions" subregistry has the policy | |||
he allocation of function | "Expert Review" | |||
(<xref section="4.5" sectionFormat="of" target="RFC8126" format="default" derive | ||||
dLink="https://rfc-editor.org/rfc/rfc8126#section-4.5" derivedContent="RFC8126"/ | ||||
>).</t> | ||||
<t anchor="de-instructions" indent="0" pn="section-3.2-2">The experts ar | ||||
e instructed to be frugal in the allocation of function | ||||
extension names that are suggestive of generally applicable semantics, | extension names that are suggestive of generally applicable semantics, | |||
keeping them in reserve for functions that are likely to enjoy wide | keeping them in reserve for functions that are likely to enjoy wide | |||
use and can make good use of their conciseness. | use and can make good use of their conciseness. | |||
The expert is also instructed to direct the registrant to provide a | The expert is also instructed to direct the registrant to provide a | |||
specification (<xref section="4.6" sectionFormat="of" target="BCP26"/>), but can | specification (<xref section="4.6" sectionFormat="of" target="RFC8126" format="d | |||
make exceptions, | efault" derivedLink="https://rfc-editor.org/rfc/rfc8126#section-4.6" derivedCont | |||
for instance when a specification is not available at the time of | ent="RFC8126"/>) but can make exceptions, | |||
for instance, when a specification is not available at the time of | ||||
registration but is likely forthcoming. | registration but is likely forthcoming. | |||
If the expert becomes aware of function extensions that are deployed and | If the expert becomes aware of function extensions that are deployed and | |||
in use, they may also initiate a registration on their own if | in use, they may also initiate a registration on their own if | |||
they deem such a registration can avert potential future collisions.</t> | they deem such a registration can avert potential future collisions.</t> | |||
<t>Each entry in the sub-registry must include:</t> | <t indent="0" pn="section-3.2-3">Each entry in the subregistry must incl | |||
<dl newline="true"> | ude the following:</t> | |||
<dt>Function Name:</dt> | <dl newline="true" indent="3" spacing="normal" pn="section-3.2-4"> | |||
<dd> | <dt pn="section-3.2-4.1">Function Name:</dt> | |||
<t>a lower case ASCII <xref target="STD80"/> string that starts with | <dd pn="section-3.2-4.2"> | |||
a letter and can | <t indent="0" pn="section-3.2-4.2.1">A lowercase ASCII <xref target= | |||
contain letters, digits and underscore characters afterwards | "RFC0020" format="default" sectionFormat="of" derivedContent="RFC0020"/> string | |||
(<tt>[a-z][_a-z0-9]*</tt>). No other entry in the sub-registry can have the | that starts with a letter and can | |||
contain letters, digits, and underscore characters afterwards | ||||
(<tt>[a-z][_a-z0-9]*</tt>). No other entry in the subregistry can have the | ||||
same function name.</t> | same function name.</t> | |||
</dd> | </dd> | |||
<dt>Brief description:</dt> | <dt pn="section-3.2-4.3">Brief description:</dt> | |||
<dd> | <dd pn="section-3.2-4.4"> | |||
<t>a brief description</t> | <t indent="0" pn="section-3.2-4.4.1">A brief description</t> | |||
</dd> | </dd> | |||
<dt>Parameters:</dt> | <dt pn="section-3.2-4.5">Parameters:</dt> | |||
<dd> | <dd pn="section-3.2-4.6"> | |||
<t>A comma-separated list of zero or more declared types, one for ea | <t indent="0" pn="section-3.2-4.6.1">A comma-separated list of zero | |||
ch of the | or more declared types, one for each of the | |||
arguments expected for this function extension</t> | arguments expected for this function extension</t> | |||
</dd> | </dd> | |||
<dt>Result:</dt> | <dt pn="section-3.2-4.7">Result:</dt> | |||
<dd> | <dd pn="section-3.2-4.8"> | |||
<t>The declared type of the result for this function extension</t> | <t indent="0" pn="section-3.2-4.8.1">The declared type of the result | |||
for this function extension</t> | ||||
</dd> | </dd> | |||
<dt>Change Controller:</dt> | <dt pn="section-3.2-4.9">Change Controller:</dt> | |||
<dd> | <dd pn="section-3.2-4.10"> | |||
<t>(see <xref section="2.3" sectionFormat="of" target="BCP26"/>)</t> | <t indent="0" pn="section-3.2-4.10.1">See <xref section="2.3" sectio | |||
nFormat="of" target="RFC8126" format="default" derivedLink="https://rfc-editor.o | ||||
rg/rfc/rfc8126#section-2.3" derivedContent="RFC8126"/>.</t> | ||||
</dd> | </dd> | |||
<dt>Reference:</dt> | <dt pn="section-3.2-4.11">Reference:</dt> | |||
<dd> | <dd pn="section-3.2-4.12"> | |||
<t>a reference document that provides a description of the function | <t indent="0" pn="section-3.2-4.12.1">A reference document that prov | |||
ides a description of the function | ||||
extension</t> | extension</t> | |||
</dd> | </dd> | |||
</dl> | </dl> | |||
<t>Initial entries in this sub-registry are as listed in <xref target="p | <t indent="0" pn="section-3.2-5">The initial entries in this subregistry | |||
re-reg"/>; the | are listed in <xref target="pre-reg" format="default" sectionFormat="of" derive | |||
entries in the Column "Change Controller" all have the value "IETF" | dContent="Table 19"/>; the | |||
and the entries in the column | entries in the "Change Controller" column all have the value "IETF", | |||
"Reference" all have the value "<xref target="fnex"/> of RFCXXXX":</t> | and the entries in the | |||
<table anchor="pre-reg"> | "Reference" column all have the value "<xref target="fnex" format="default" sect | |||
<name>Initial Entries in the Function Extensions Subregistry</name> | ionFormat="of" derivedContent="Section 2.4"/> of RFC 9535":</t> | |||
<table anchor="pre-reg" align="center" pn="table-19"> | ||||
<name slugifiedName="name-initial-entries-in-the-func">Initial Entries | ||||
in the Function Extensions Subregistry</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">Function Name</th> | <th align="left" colspan="1" rowspan="1">Function Name</th> | |||
<th align="left">Brief description</th> | <th align="left" colspan="1" rowspan="1">Brief Description</th> | |||
<th align="left">Parameters</th> | <th align="left" colspan="1" rowspan="1">Parameters</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left">length</td> | <td align="left" colspan="1" rowspan="1">length</td> | |||
<td align="left">length of string, array, object</td> | <td align="left" colspan="1" rowspan="1">length of string, array, | |||
<td align="left"> | or object</td> | |||
<td align="left" colspan="1" rowspan="1"> | ||||
<tt>ValueType</tt></td> | <tt>ValueType</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>ValueType</tt></td> | <tt>ValueType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">count</td> | <td align="left" colspan="1" rowspan="1">count</td> | |||
<td align="left">size of nodelist</td> | <td align="left" colspan="1" rowspan="1">size of nodelist</td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>NodesType</tt></td> | <tt>NodesType</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>ValueType</tt></td> | <tt>ValueType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">match</td> | <td align="left" colspan="1" rowspan="1">match</td> | |||
<td align="left">regular expression full match</td> | <td align="left" colspan="1" rowspan="1">regular expression full m | |||
<td align="left"> | atch</td> | |||
<td align="left" colspan="1" rowspan="1"> | ||||
<tt>ValueType</tt>, <tt>ValueType</tt></td> | <tt>ValueType</tt>, <tt>ValueType</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>LogicalType</tt></td> | <tt>LogicalType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">search</td> | <td align="left" colspan="1" rowspan="1">search</td> | |||
<td align="left">regular expression substring match</td> | <td align="left" colspan="1" rowspan="1">regular expression substr | |||
<td align="left"> | ing match</td> | |||
<td align="left" colspan="1" rowspan="1"> | ||||
<tt>ValueType</tt>, <tt>ValueType</tt></td> | <tt>ValueType</tt>, <tt>ValueType</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>LogicalType</tt></td> | <tt>LogicalType</tt></td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">value</td> | <td align="left" colspan="1" rowspan="1">value</td> | |||
<td align="left">value of single node in nodelist</td> | <td align="left" colspan="1" rowspan="1">value of the single node | |||
<td align="left"> | in nodelist</td> | |||
<td align="left" colspan="1" rowspan="1"> | ||||
<tt>NodesType</tt></td> | <tt>NodesType</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>ValueType</tt></td> | <tt>ValueType</tt></td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="Security"> | <section anchor="Security" numbered="true" removeInRFC="false" toc="include" | |||
<name>Security Considerations</name> | pn="section-4"> | |||
<t>Security considerations for JSONPath can stem from</t> | <name slugifiedName="name-security-considerations">Security Considerations | |||
<ul spacing="normal"> | </name> | |||
<li>attack vectors on JSONPath implementations,</li> | <t indent="0" pn="section-4-1">Security considerations for JSONPath can st | |||
<li>attack vectors on how JSONPath queries are formed, and</li> | em from:</t> | |||
<li>the way JSONPath is used in security-relevant mechanisms.</li> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-4-2 | |||
"> | ||||
<li pn="section-4-2.1">attack vectors on JSONPath implementations,</li> | ||||
<li pn="section-4-2.2">attack vectors on how JSONPath queries are formed | ||||
, and</li> | ||||
<li pn="section-4-2.3">the way JSONPath is used in security-relevant mec | ||||
hanisms.</li> | ||||
</ul> | </ul> | |||
<section anchor="attack-vectors-on-jsonpath-implementations"> | <section anchor="attack-vectors-on-jsonpath-implementations" numbered="tru | |||
<name>Attack Vectors on JSONPath Implementations</name> | e" removeInRFC="false" toc="include" pn="section-4.1"> | |||
<t>Historically, JSONPath has often been implemented by feeding parts of | <name slugifiedName="name-attack-vectors-on-jsonpath-">Attack Vectors on | |||
JSONPath Implementations</name> | ||||
<t indent="0" pn="section-4.1-1">Historically, JSONPath has often been i | ||||
mplemented by feeding parts of | ||||
the query to an underlying programming language engine, e.g., | the query to an underlying programming language engine, e.g., | |||
JavaScript's <tt>eval()</tt> function. | JavaScript's <tt>eval()</tt> function. | |||
This approach is well known to lead to injection attacks and would | This approach is well known to lead to injection attacks and would | |||
require perfect input validation to prevent these attacks (see | require perfect input validation to prevent these attacks (see | |||
<xref section="12" sectionFormat="of" target="RFC8259"/> for similar considerati ons for JSON itself). | <xref section="12" sectionFormat="of" target="RFC8259" format="default" derivedL ink="https://rfc-editor.org/rfc/rfc8259#section-12" derivedContent="RFC8259"/> f or similar considerations for JSON itself). | |||
Instead, JSONPath implementations need to implement the entire syntax | Instead, JSONPath implementations need to implement the entire syntax | |||
of the query without relying on the parsers of programming language | of the query without relying on the parsers of programming language | |||
engines.</t> | engines.</t> | |||
<t>Attacks on availability may attempt to trigger unusually expensive | <t indent="0" pn="section-4.1-2">Attacks on availability may attempt to trigger unusually expensive | |||
runtime performance exhibited by certain implementations in certain | runtime performance exhibited by certain implementations in certain | |||
cases. | cases. | |||
(See <xref section="10" sectionFormat="of" target="RFC8949"/> for issues in hash | (See <xref section="10" sectionFormat="of" target="RFC8949" format="default" der | |||
-table implementations, | ivedLink="https://rfc-editor.org/rfc/rfc8949#section-10" derivedContent="RFC8949 | |||
and <xref section="8" sectionFormat="of" target="I-D.draft-ietf-jsonpath-iregexp | "/> for issues in hash-table implementations | |||
"/> for performance issues in regular | and <xref section="8" sectionFormat="of" target="RFC9485" format="default" deriv | |||
edLink="https://rfc-editor.org/rfc/rfc9485#section-8" derivedContent="RFC9485"/> | ||||
for performance issues in regular | ||||
expression implementations.) | expression implementations.) | |||
Implementers need to be aware that good average performance is not | Implementers need to be aware that good average performance is not | |||
sufficient as long as an attacker can choose to submit specially | sufficient as long as an attacker can choose to submit specially | |||
crafted JSONPath queries or query arguments that trigger surprisingly high, poss ibly | crafted JSONPath queries or query arguments that trigger surprisingly high, poss ibly | |||
exponential, CPU usage or, for example via a naive recursive implementation of t he descendant segment, | exponential, CPU usage or, for example, via a naive recursive implementation of the descendant segment, | |||
stack overflow. Implementations need to have appropriate resource management | stack overflow. Implementations need to have appropriate resource management | |||
to mitigate these attacks.</t> | to mitigate these attacks.</t> | |||
</section> | </section> | |||
<section anchor="attack-vectors-on-how-jsonpath-queries-are-formed"> | <section anchor="attack-vectors-on-how-jsonpath-queries-are-formed" number | |||
<name>Attack Vectors on How JSONPath Queries are Formed</name> | ed="true" removeInRFC="false" toc="include" pn="section-4.2"> | |||
<t>JSONPath queries are often not static, but formed from variables that | <name slugifiedName="name-attack-vectors-on-how-jsonp">Attack Vectors on | |||
How JSONPath Queries Are Formed</name> | ||||
<t indent="0" pn="section-4.2-1">JSONPath queries are often not static b | ||||
ut formed from variables that | ||||
provide index values, member names, or values to compare with in a | provide index values, member names, or values to compare with in a | |||
filter expression. | filter expression. | |||
These variables need to be validated (e.g., only allowing specific constructs | These variables need to be validated (e.g., only allowing specific constructs | |||
such as .name to be formed when the given values allow that) and translated | such as .name to be formed when the given values allow that) and translated | |||
(e.g., by escaping string delimiters). | (e.g., by escaping string delimiters). | |||
Not performing these validations and translations correctly can lead to unexpect ed | Not performing these validations and translations correctly can lead to unexpect ed | |||
failures, which can lead to Availability, Confidentiality, and | failures, which can lead to availability, confidentiality, and | |||
Integrity breaches, in particular if an adversary has control over the | integrity breaches, in particular, if an adversary has control over the | |||
values (e.g., by entering them into a Web form). | values (e.g., by entering them into a web form). | |||
The resulting class of attacks, <em>injections</em> (e.g., SQL injections), | The resulting class of attacks, <em>injections</em> (e.g., SQL injections), | |||
is consistently found among the top causes of application security | is consistently found among the top causes of application security | |||
vulnerabilities and requires particular attention.</t> | vulnerabilities and requires particular attention.</t> | |||
</section> | </section> | |||
<section anchor="attacks-on-security-mechanisms-that-employ-jsonpath"> | <section anchor="attacks-on-security-mechanisms-that-employ-jsonpath" numb | |||
<name>Attacks on Security Mechanisms that Employ JSONPath</name> | ered="true" removeInRFC="false" toc="include" pn="section-4.3"> | |||
<t>Where JSONPath is used as a part of a security mechanism, attackers | <name slugifiedName="name-attacks-on-security-mechani">Attacks on Securi | |||
can attempt to provoke unexpected or unpredictable behavior, or | ty Mechanisms That Employ JSONPath</name> | |||
<t indent="0" pn="section-4.3-1">Where JSONPath is used as a part of a s | ||||
ecurity mechanism, attackers | ||||
can attempt to provoke unexpected or unpredictable behavior or | ||||
take advantage of differences in behavior between JSONPath implementations.</t> | take advantage of differences in behavior between JSONPath implementations.</t> | |||
<t>Unexpected or unpredictable behavior can arise from a query argument | <t indent="0" pn="section-4.3-2">Unexpected or unpredictable behavior ca | |||
with certain | n arise from a query argument with certain | |||
constructs described as unpredictable by <xref target="RFC8259"/>. | constructs described as unpredictable by <xref target="RFC8259" format="default" | |||
sectionFormat="of" derivedContent="RFC8259"/>. | ||||
Predictable behavior can be expected, except in relation to the ordering | Predictable behavior can be expected, except in relation to the ordering | |||
of objects, for any query argument conforming with <xref target="RFC7493"/>.</t> | of objects, for any query argument conforming with <xref target="RFC7493" format | |||
<t>Other attacks can target the behavior of underlying technologies such | ="default" sectionFormat="of" derivedContent="RFC7493"/>.</t> | |||
as UTF-8 (see | <t indent="0" pn="section-4.3-3">Other attacks can target the behavior o | |||
<xref section="10" sectionFormat="of" target="RFC3629"/>) and the Unicode charac | f underlying technologies, such as UTF-8 (see | |||
ter set.</t> | <xref section="10" sectionFormat="of" target="RFC3629" format="default" derivedL | |||
ink="https://rfc-editor.org/rfc/rfc3629#section-10" derivedContent="RFC3629"/>) | ||||
and the Unicode character set.</t> | ||||
</section> | </section> | |||
</section> | </section> | |||
</middle> | </middle> | |||
<back> | <back> | |||
<references> | <references pn="section-5"> | |||
<name>References</name> | <name slugifiedName="name-references">References</name> | |||
<references anchor="sec-normative-references"> | <references anchor="sec-normative-references" pn="section-5.1"> | |||
<name>Normative References</name> | <name slugifiedName="name-normative-references">Normative References</na | |||
<reference anchor="STD80"> | me> | |||
<reference anchor="RFC0020" target="https://www.rfc-editor.org/info/rfc2 | ||||
0" quoteTitle="true" derivedAnchor="RFC0020"> | ||||
<front> | <front> | |||
<title>ASCII format for network interchange</title> | <title>ASCII format for network interchange</title> | |||
<author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/> | <author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/> | |||
<date month="October" year="1969"/> | <date month="October" year="1969"/> | |||
</front> | </front> | |||
<seriesInfo name="STD" value="80"/> | <seriesInfo name="STD" value="80"/> | |||
<seriesInfo name="RFC" value="20"/> | <seriesInfo name="RFC" value="20"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC0020"/> | <seriesInfo name="DOI" value="10.17487/RFC0020"/> | |||
</reference> | </reference> | |||
<reference anchor="BCP26"> | <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2 119" quoteTitle="true" derivedAnchor="RFC2119"> | |||
<front> | <front> | |||
<title>Guidelines for Writing an IANA Considerations Section in RFCs | <title>Key words for use in RFCs to Indicate Requirement Levels</tit | |||
</title> | le> | |||
<author fullname="M. Cotton" initials="M." surname="Cotton"/> | <author fullname="S. Bradner" initials="S." surname="Bradner"/> | |||
<author fullname="B. Leiba" initials="B." surname="Leiba"/> | <date month="March" year="1997"/> | |||
<author fullname="T. Narten" initials="T." surname="Narten"/> | ||||
<date month="June" year="2017"/> | ||||
<abstract> | <abstract> | |||
<t>Many protocols make use of points of extensibility that use con | <t indent="0">In many standards track documents several words are | |||
stants to identify various protocol parameters. To ensure that the values in the | used to signify the requirements in the specification. These words are often cap | |||
se fields do not have conflicting uses and to promote interoperability, their al | italized. This document defines these words as they should be interpreted in IET | |||
locations are often coordinated by a central record keeper. For IETF protocols, | F documents. This document specifies an Internet Best Current Practices for the | |||
that role is filled by the Internet Assigned Numbers Authority (IANA).</t> | Internet Community, and requests discussion and suggestions for improvements.</t | |||
<t>To make assignments in a given registry prudently, guidance des | > | |||
cribing the conditions under which new values should be assigned, as well as whe | ||||
n and how modifications to existing values can be made, is needed. This document | ||||
defines a framework for the documentation of these guidelines by specification | ||||
authors, in order to assure that the provided guidance for the IANA Consideratio | ||||
ns is clear and addresses the various issues that are likely in the operation of | ||||
a registry.</t> | ||||
<t>This is the third edition of this document; it obsoletes RFC 52 | ||||
26.</t> | ||||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="BCP" value="26"/> | <seriesInfo name="BCP" value="14"/> | |||
<seriesInfo name="RFC" value="8126"/> | <seriesInfo name="RFC" value="2119"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC8126"/> | <seriesInfo name="DOI" value="10.17487/RFC2119"/> | |||
</reference> | </reference> | |||
<reference anchor="RFC3629"> | <reference anchor="RFC3629" target="https://www.rfc-editor.org/info/rfc3 629" quoteTitle="true" derivedAnchor="RFC3629"> | |||
<front> | <front> | |||
<title>UTF-8, a transformation format of ISO 10646</title> | <title>UTF-8, a transformation format of ISO 10646</title> | |||
<author fullname="F. Yergeau" initials="F." surname="Yergeau"/> | <author fullname="F. Yergeau" initials="F." surname="Yergeau"/> | |||
<date month="November" year="2003"/> | <date month="November" year="2003"/> | |||
<abstract> | <abstract> | |||
<t>ISO/IEC 10646-1 defines a large character set called the Univer sal Character Set (UCS) which encompasses most of the world's writing systems. T he originally proposed encodings of the UCS, however, were not compatible with m any current applications and protocols, and this has led to the development of U TF-8, the object of this memo. UTF-8 has the characteristic of preserving the fu ll US-ASCII range, providing compatibility with file systems, parsers and other software that rely on US-ASCII values but are transparent to other values. This memo obsoletes and replaces RFC 2279.</t> | <t indent="0">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 compat ible with many current applications and protocols, and this has led to the devel opment of UTF-8, the object of this memo. UTF-8 has the characteristic of preser ving 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 va lues. This memo obsoletes and replaces RFC 2279.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="STD" value="63"/> | <seriesInfo name="STD" value="63"/> | |||
<seriesInfo name="RFC" value="3629"/> | <seriesInfo name="RFC" value="3629"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC3629"/> | <seriesInfo name="DOI" value="10.17487/RFC3629"/> | |||
</reference> | </reference> | |||
<reference anchor="RFC5234"> | <reference anchor="RFC5234" target="https://www.rfc-editor.org/info/rfc5 234" quoteTitle="true" derivedAnchor="RFC5234"> | |||
<front> | <front> | |||
<title>Augmented BNF for Syntax Specifications: ABNF</title> | <title>Augmented BNF for Syntax Specifications: ABNF</title> | |||
<author fullname="D. Crocker" initials="D." role="editor" surname="C rocker"/> | <author fullname="D. Crocker" initials="D." role="editor" surname="C rocker"/> | |||
<author fullname="P. Overell" initials="P." surname="Overell"/> | <author fullname="P. Overell" initials="P." surname="Overell"/> | |||
<date month="January" year="2008"/> | <date month="January" year="2008"/> | |||
<abstract> | <abstract> | |||
<t>Internet technical specifications often need to define a formal syntax. Over the years, a modified version of Backus-Naur Form (BNF), called Au gmented BNF (ABNF), has been popular among many Internet specifications. The cur rent specification documents ABNF. It balances compactness and simplicity with r easonable representational power. The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ra nges. This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specification s. [STANDARDS-TRACK]</t> | <t indent="0">Internet technical specifications often need to defi ne a formal syntax. Over the years, a modified version of Backus-Naur Form (BNF) , called Augmented BNF (ABNF), has been popular among many Internet specificatio ns. The current specification documents ABNF. It balances compactness and simpli city with reasonable representational power. The differences between standard BN F and ABNF involve naming rules, repetition, alternatives, order-independence, a nd value ranges. This specification also supplies additional rule definitions an d encoding for a core lexical analyzer of the type common to several Internet sp ecifications. [STANDARDS-TRACK]</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="STD" value="68"/> | <seriesInfo name="STD" value="68"/> | |||
<seriesInfo name="RFC" value="5234"/> | <seriesInfo name="RFC" value="5234"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC5234"/> | <seriesInfo name="DOI" value="10.17487/RFC5234"/> | |||
</reference> | </reference> | |||
<reference anchor="RFC8259"> | <reference anchor="RFC6838" target="https://www.rfc-editor.org/info/rfc6 | |||
<front> | 838" quoteTitle="true" derivedAnchor="RFC6838"> | |||
<title>The JavaScript Object Notation (JSON) Data Interchange Format | ||||
</title> | ||||
<author fullname="T. Bray" initials="T." role="editor" surname="Bray | ||||
"/> | ||||
<date month="December" year="2017"/> | ||||
<abstract> | ||||
<t>JavaScript Object Notation (JSON) is a lightweight, text-based, | ||||
language-independent data interchange format. It was derived from the ECMAScrip | ||||
t Programming Language Standard. JSON defines a small set of formatting rules fo | ||||
r the portable representation of structured data.</t> | ||||
<t>This document removes inconsistencies with other specifications | ||||
of JSON, repairs specification errors, and offers experience-based interoperabi | ||||
lity guidance.</t> | ||||
</abstract> | ||||
</front> | ||||
<seriesInfo name="STD" value="90"/> | ||||
<seriesInfo name="RFC" value="8259"/> | ||||
<seriesInfo name="DOI" value="10.17487/RFC8259"/> | ||||
</reference> | ||||
<reference anchor="RFC7493"> | ||||
<front> | ||||
<title>The I-JSON Message Format</title> | ||||
<author fullname="T. Bray" initials="T." role="editor" surname="Bray | ||||
"/> | ||||
<date month="March" year="2015"/> | ||||
<abstract> | ||||
<t>I-JSON (short for "Internet JSON") is a restricted profile of J | ||||
SON designed to maximize interoperability and increase confidence that software | ||||
can process it successfully with predictable results.</t> | ||||
</abstract> | ||||
</front> | ||||
<seriesInfo name="RFC" value="7493"/> | ||||
<seriesInfo name="DOI" value="10.17487/RFC7493"/> | ||||
</reference> | ||||
<reference anchor="RFC6838"> | ||||
<front> | <front> | |||
<title>Media Type Specifications and Registration Procedures</title> | <title>Media Type Specifications and Registration Procedures</title> | |||
<author fullname="N. Freed" initials="N." surname="Freed"/> | <author fullname="N. Freed" initials="N." surname="Freed"/> | |||
<author fullname="J. Klensin" initials="J." surname="Klensin"/> | <author fullname="J. Klensin" initials="J." surname="Klensin"/> | |||
<author fullname="T. Hansen" initials="T." surname="Hansen"/> | <author fullname="T. Hansen" initials="T." surname="Hansen"/> | |||
<date month="January" year="2013"/> | <date month="January" year="2013"/> | |||
<abstract> | <abstract> | |||
<t>This document defines procedures for the specification and regi stration of media types for use in HTTP, MIME, and other Internet protocols. Thi s memo documents an Internet Best Current Practice.</t> | <t indent="0">This document defines procedures for the specificati on and registration of media types for use in HTTP, MIME, and other Internet pro tocols. This memo documents an Internet Best Current Practice.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="BCP" value="13"/> | <seriesInfo name="BCP" value="13"/> | |||
<seriesInfo name="RFC" value="6838"/> | <seriesInfo name="RFC" value="6838"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC6838"/> | <seriesInfo name="DOI" value="10.17487/RFC6838"/> | |||
</reference> | </reference> | |||
<reference anchor="I-D.draft-ietf-jsonpath-iregexp"> | <reference anchor="RFC7493" target="https://www.rfc-editor.org/info/rfc7 493" quoteTitle="true" derivedAnchor="RFC7493"> | |||
<front> | <front> | |||
<title>I-Regexp: An Interoperable Regexp Format</title> | <title>The I-JSON Message Format</title> | |||
<author fullname="Carsten Bormann" initials="C." surname="Bormann"> | <author fullname="T. Bray" initials="T." role="editor" surname="Bray | |||
<organization>Universität Bremen TZI</organization> | "/> | |||
</author> | <date month="March" year="2015"/> | |||
<author fullname="Tim Bray" initials="T." surname="Bray"> | ||||
<organization>Textuality</organization> | ||||
</author> | ||||
<date day="29" month="June" year="2023"/> | ||||
<abstract> | <abstract> | |||
<t> This document specifies I-Regexp, a flavor of regular expres | <t indent="0">I-JSON (short for "Internet JSON") is a restricted p | |||
sions | rofile of JSON designed to maximize interoperability and increase confidence tha | |||
that is limited in scope with the goal of interoperation across many | t software can process it successfully with predictable results.</t> | |||
different regular-expression libraries. | ||||
</t> | ||||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="Internet-Draft" value="draft-ietf-jsonpath-iregexp-0 | <seriesInfo name="RFC" value="7493"/> | |||
8"/> | <seriesInfo name="DOI" value="10.17487/RFC7493"/> | |||
</reference> | ||||
<reference anchor="UNICODE" target="https://www.unicode.org/versions/Uni | ||||
code14.0.0/UnicodeStandard-14.0.pdf"> | ||||
<front> | ||||
<title>The Unicode® Standard: Version 14.0 - Core Specification</tit | ||||
le> | ||||
<author> | ||||
<organization>The Unicode Consortium</organization> | ||||
</author> | ||||
<date year="2021" month="September"/> | ||||
</front> | ||||
</reference> | </reference> | |||
<reference anchor="RFC2119"> | <reference anchor="RFC8126" target="https://www.rfc-editor.org/info/rfc8 126" quoteTitle="true" derivedAnchor="RFC8126"> | |||
<front> | <front> | |||
<title>Key words for use in RFCs to Indicate Requirement Levels</tit | <title>Guidelines for Writing an IANA Considerations Section in RFCs | |||
le> | </title> | |||
<author fullname="S. Bradner" initials="S." surname="Bradner"/> | <author fullname="M. Cotton" initials="M." surname="Cotton"/> | |||
<date month="March" year="1997"/> | <author fullname="B. Leiba" initials="B." surname="Leiba"/> | |||
<author fullname="T. Narten" initials="T." surname="Narten"/> | ||||
<date month="June" year="2017"/> | ||||
<abstract> | <abstract> | |||
<t>In many standards track documents several words are used to sig | <t indent="0">Many protocols make use of points of extensibility t | |||
nify the requirements in the specification. These words are often capitalized. T | hat use constants to identify various protocol parameters. To ensure that the va | |||
his document defines these words as they should be interpreted in IETF documents | lues in these fields do not have conflicting uses and to promote interoperabilit | |||
. This document specifies an Internet Best Current Practices for the Internet Co | y, their allocations are often coordinated by a central record keeper. For IETF | |||
mmunity, and requests discussion and suggestions for improvements.</t> | protocols, that role is filled by the Internet Assigned Numbers Authority (IANA) | |||
.</t> | ||||
<t indent="0">To make assignments in a given registry prudently, g | ||||
uidance 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. Th | ||||
is document defines a framework for the documentation of these guidelines by spe | ||||
cification authors, in order to assure that the provided guidance for the IANA C | ||||
onsiderations is clear and addresses the various issues that are likely in the o | ||||
peration of a registry.</t> | ||||
<t indent="0">This is the third edition of this document; it obsol | ||||
etes RFC 5226.</t> | ||||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="BCP" value="14"/> | <seriesInfo name="BCP" value="26"/> | |||
<seriesInfo name="RFC" value="2119"/> | <seriesInfo name="RFC" value="8126"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC2119"/> | <seriesInfo name="DOI" value="10.17487/RFC8126"/> | |||
</reference> | </reference> | |||
<reference anchor="RFC8174"> | <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8 174" quoteTitle="true" derivedAnchor="RFC8174"> | |||
<front> | <front> | |||
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</ti tle> | <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</ti tle> | |||
<author fullname="B. Leiba" initials="B." surname="Leiba"/> | <author fullname="B. Leiba" initials="B." surname="Leiba"/> | |||
<date month="May" year="2017"/> | <date month="May" year="2017"/> | |||
<abstract> | <abstract> | |||
<t>RFC 2119 specifies common key words that may be used in protoco l specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t> | <t indent="0">RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clari fying that only UPPERCASE usage of the key words have the defined special meanin gs.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="BCP" value="14"/> | <seriesInfo name="BCP" value="14"/> | |||
<seriesInfo name="RFC" value="8174"/> | <seriesInfo name="RFC" value="8174"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC8174"/> | <seriesInfo name="DOI" value="10.17487/RFC8174"/> | |||
</reference> | </reference> | |||
</references> | <reference anchor="RFC8259" target="https://www.rfc-editor.org/info/rfc8 | |||
<references anchor="sec-informative-references"> | 259" quoteTitle="true" derivedAnchor="RFC8259"> | |||
<name>Informative References</name> | ||||
<reference anchor="COMPARISON" target="https://cburgmer.github.io/json-p | ||||
ath-comparison/"> | ||||
<front> | <front> | |||
<title>JSONPath Comparison</title> | <title>The JavaScript Object Notation (JSON) Data Interchange Format | |||
<author initials="C." surname="Burgmer" fullname="Christoph Burgmer" | </title> | |||
> | <author fullname="T. Bray" initials="T." role="editor" surname="Bray | |||
<organization>Thoughtworks</organization> | "/> | |||
</author> | <date month="December" year="2017"/> | |||
<date>n.d.</date> | <abstract> | |||
<t indent="0">JavaScript Object Notation (JSON) is a lightweight, | ||||
text-based, language-independent data interchange format. It was derived from th | ||||
e ECMAScript Programming Language Standard. JSON defines a small set of formatti | ||||
ng rules for the portable representation of structured data.</t> | ||||
<t indent="0">This document removes inconsistencies with other spe | ||||
cifications of JSON, repairs specification errors, and offers experience-based i | ||||
nteroperability guidance.</t> | ||||
</abstract> | ||||
</front> | </front> | |||
<seriesInfo name="STD" value="90"/> | ||||
<seriesInfo name="RFC" value="8259"/> | ||||
<seriesInfo name="DOI" value="10.17487/RFC8259"/> | ||||
</reference> | </reference> | |||
<reference anchor="RFC6901"> | <reference anchor="RFC9485" target="https://www.rfc-editor.org/info/rfc9 485" quoteTitle="true" derivedAnchor="RFC9485"> | |||
<front> | <front> | |||
<title>JavaScript Object Notation (JSON) Pointer</title> | <title>I-Regexp: An Interoperable Regular Expression Format</title> | |||
<author fullname="P. Bryan" initials="P." role="editor" surname="Bry | <author fullname="C. Bormann" initials="C." surname="Bormann"/> | |||
an"/> | <author fullname="T. Bray" initials="T." surname="Bray"/> | |||
<author fullname="K. Zyp" initials="K." surname="Zyp"/> | <date month="October" year="2023"/> | |||
<author fullname="M. Nottingham" initials="M." role="editor" surname | ||||
="Nottingham"/> | ||||
<date month="April" year="2013"/> | ||||
<abstract> | <abstract> | |||
<t>JSON Pointer defines a string syntax for identifying a specific value within a JavaScript Object Notation (JSON) document.</t> | <t indent="0">This document specifies I-Regexp, a flavor of regula r expression that is limited in scope with the goal of interoperation across man y different regular expression libraries.</t> | |||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="RFC" value="6901"/> | <seriesInfo name="RFC" value="9485"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC6901"/> | <seriesInfo name="DOI" value="10.17487/RFC9485"/> | |||
</reference> | </reference> | |||
<reference anchor="JSONPath-orig" target="https://goessner.net/articles/ JsonPath/"> | <reference anchor="UNICODE" target="https://www.unicode.org/versions/lat est/" quoteTitle="true" derivedAnchor="UNICODE"> | |||
<front> | <front> | |||
<title>JSONPath — XPath for JSON</title> | <title>The Unicode® Standard</title> | |||
<author initials="S." surname="Gössner" fullname="Stefan Gössner"> | <author> | |||
<organization>Fachhochschule Dortmund</organization> | <organization showOnFrontPage="true">The Unicode Consortium</organ | |||
ization> | ||||
</author> | </author> | |||
<date year="2007" month="February" day="21"/> | ||||
</front> | </front> | |||
<annotation>At the time of writing, <eref target="https://www.unicode. org/versions/Unicode15.0.0/UnicodeStandard-15.0.pdf" brackets="angle"/>.</annota tion> | ||||
</reference> | </reference> | |||
<reference anchor="XPath" target="https://www.w3.org/TR/2010/REC-xpath20 | </references> | |||
-20101214/"> | <references anchor="sec-informative-references" pn="section-5.2"> | |||
<name slugifiedName="name-informative-references">Informative References | ||||
</name> | ||||
<reference anchor="BOOLEAN-LAWS" target="https://en.wikipedia.org/w/inde | ||||
x.php?title=Boolean_algebra&oldid=1191386550#Laws" quoteTitle="true" derived | ||||
Anchor="BOOLEAN-LAWS"> | ||||
<front> | <front> | |||
<title>XML Path Language (XPath) 2.0 (Second Edition)</title> | <title>Boolean algebra: Laws</title> | |||
<author fullname="Anders Berglund" role="editor"/> | <author> | |||
<author fullname="Don Chamberlin" role="editor"/> | <organization showOnFrontPage="true"/> | |||
<author fullname="Jerome Simeon" role="editor"/> | </author> | |||
<author fullname="Jonathan Robie" role="editor"/> | <date month="December" year="2023"/> | |||
<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> | </front> | |||
<seriesInfo name="W3C REC" value="REC-xpath20-20101214"/> | ||||
<seriesInfo name="W3C" value="REC-xpath20-20101214"/> | ||||
</reference> | </reference> | |||
<reference anchor="E4X"> | <reference anchor="COMPARISON" target="https://cburgmer.github.io/json-p ath-comparison/" quoteTitle="true" derivedAnchor="COMPARISON"> | |||
<front> | <front> | |||
<title>Information technology — ECMAScript for XML (E4X) specificati | <title>JSONPath Comparison</title> | |||
on</title> | <author initials="C." surname="Burgmer" fullname="Christoph Burgmer" | |||
<author> | > | |||
<organization>ISO</organization> | <organization showOnFrontPage="true">Thoughtworks</organization> | |||
</author> | </author> | |||
<date year="2006"/> | ||||
</front> | </front> | |||
<seriesInfo name="ISO/IEC 22537:2006" value=""/> | ||||
</reference> | </reference> | |||
<reference anchor="SLICE" target="https://github.com/tc39/proposal-slice -notation"> | <reference anchor="E4X" target="https://www.iso.org/standard/41002.html" quoteTitle="true" derivedAnchor="E4X"> | |||
<front> | <front> | |||
<title>Slice notation</title> | <title>Information technology - ECMAScript for XML (E4X) specificati on</title> | |||
<author> | <author> | |||
<organization/> | <organization showOnFrontPage="true">ISO</organization> | |||
</author> | </author> | |||
<date>n.d.</date> | <date year="2006" month="February"/> | |||
</front> | </front> | |||
<seriesInfo 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/sta | ||||
ndards/ecma-357" brackets="angle"/>.</annotation> | ||||
</reference> | </reference> | |||
<reference anchor="ECMA-262" target="https://www.ecma-international.org/ wp-content/uploads/ECMA-262_3rd_edition_december_1999.pdf"> | <reference anchor="ECMA-262" target="https://www.ecma-international.org/ wp-content/uploads/ECMA-262_3rd_edition_december_1999.pdf" quoteTitle="true" der ivedAnchor="ECMA-262"> | |||
<front> | <front> | |||
<title>ECMAScript Language Specification, Standard ECMA-262, Third E dition</title> | <title>ECMAScript Language Specification</title> | |||
<author> | <author> | |||
<organization>Ecma International</organization> | <organization showOnFrontPage="true">ECMA International</organizat ion> | |||
</author> | </author> | |||
<date year="1999" month="December"/> | <date year="1999" month="December"/> | |||
</front> | </front> | |||
<refcontent>Standard ECMA-262, Third Edition</refcontent> | ||||
</reference> | </reference> | |||
<reference anchor="RFC8949"> | <reference anchor="JSONPath-orig" target="https://goessner.net/articles/ | |||
JsonPath/" quoteTitle="true" derivedAnchor="JSONPath-orig"> | ||||
<front> | ||||
<title>JSONPath - XPath for JSON</title> | ||||
<author initials="S." surname="Gössner" fullname="Stefan Gössner"> | ||||
<organization showOnFrontPage="true">Fachhochschule Dortmund</orga | ||||
nization> | ||||
</author> | ||||
<date year="2007" month="February"/> | ||||
</front> | ||||
</reference> | ||||
<reference anchor="RFC6901" target="https://www.rfc-editor.org/info/rfc6 | ||||
901" quoteTitle="true" derivedAnchor="RFC6901"> | ||||
<front> | ||||
<title>JavaScript Object Notation (JSON) Pointer</title> | ||||
<author fullname="P. Bryan" initials="P." role="editor" surname="Bry | ||||
an"/> | ||||
<author fullname="K. Zyp" initials="K." surname="Zyp"/> | ||||
<author fullname="M. Nottingham" initials="M." role="editor" surname | ||||
="Nottingham"/> | ||||
<date month="April" year="2013"/> | ||||
<abstract> | ||||
<t indent="0">JSON Pointer defines a string syntax for identifying | ||||
a specific value within a JavaScript Object Notation (JSON) document.</t> | ||||
</abstract> | ||||
</front> | ||||
<seriesInfo name="RFC" value="6901"/> | ||||
<seriesInfo name="DOI" value="10.17487/RFC6901"/> | ||||
</reference> | ||||
<reference anchor="RFC8949" target="https://www.rfc-editor.org/info/rfc8 | ||||
949" quoteTitle="true" derivedAnchor="RFC8949"> | ||||
<front> | <front> | |||
<title>Concise Binary Object Representation (CBOR)</title> | <title>Concise Binary Object Representation (CBOR)</title> | |||
<author fullname="C. Bormann" initials="C." surname="Bormann"/> | <author fullname="C. Bormann" initials="C." surname="Bormann"/> | |||
<author fullname="P. Hoffman" initials="P." surname="Hoffman"/> | <author fullname="P. Hoffman" initials="P." surname="Hoffman"/> | |||
<date month="December" year="2020"/> | <date month="December" year="2020"/> | |||
<abstract> | <abstract> | |||
<t>The Concise Binary Object Representation (CBOR) is a data forma | <t indent="0">The Concise Binary Object Representation (CBOR) is a | |||
t whose design goals include the possibility of extremely small code size, fairl | data format whose design goals include the possibility of extremely small code | |||
y small message size, and extensibility without the need for version negotiation | size, fairly small message size, and extensibility without the need for version | |||
. These design goals make it different from earlier binary serializations such a | negotiation. These design goals make it different from earlier binary serializat | |||
s ASN.1 and MessagePack.</t> | ions such as ASN.1 and MessagePack.</t> | |||
<t>This document obsoletes RFC 7049, providing editorial improveme | <t indent="0">This document obsoletes RFC 7049, providing editoria | |||
nts, new details, and errata fixes while keeping full compatibility with the int | l improvements, new details, and errata fixes while keeping full compatibility w | |||
erchange format of RFC 7049. It does not create a new version of the format.</t> | ith the interchange format of RFC 7049. It does not create a new version of the | |||
format.</t> | ||||
</abstract> | </abstract> | |||
</front> | </front> | |||
<seriesInfo name="STD" value="94"/> | <seriesInfo name="STD" value="94"/> | |||
<seriesInfo name="RFC" value="8949"/> | <seriesInfo name="RFC" value="8949"/> | |||
<seriesInfo name="DOI" value="10.17487/RFC8949"/> | <seriesInfo name="DOI" value="10.17487/RFC8949"/> | |||
</reference> | </reference> | |||
<reference anchor="BOOLEAN-LAWS" target="https://en.wikipedia.org/wiki/B oolean_algebra#Laws"> | <reference anchor="SLICE" target="https://github.com/tc39/proposal-slice -notation" quoteTitle="true" derivedAnchor="SLICE"> | |||
<front> | <front> | |||
<title>Boolean algebra laws</title> | <title>Slice notation</title> | |||
<author> | <author> | |||
<organization/> | <organization showOnFrontPage="true"/> | |||
</author> | </author> | |||
<date>n.d.</date> | <date month="July" year="2022"/> | |||
</front> | </front> | |||
<refcontent>commit 82f95b4</refcontent> | ||||
</reference> | ||||
<reference anchor="XPath" target="https://www.w3.org/TR/2010/REC-xpath20 | ||||
-20101214/" quoteTitle="true" derivedAnchor="XPath"> | ||||
<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> | ||||
<seriesInfo name="W3C" value="REC-xpath20-20101214"/> | ||||
</reference> | </reference> | |||
</references> | </references> | |||
</references> | </references> | |||
<?line 2296?> | <section anchor="collected-abnf-grammars" numbered="true" removeInRFC="false | |||
" toc="include" pn="section-appendix.a"> | ||||
<section anchor="collected-abnf-grammars"> | <name slugifiedName="name-collected-abnf-grammars">Collected ABNF Grammars | |||
<name>Collected ABNF grammars</name> | </name> | |||
<t>This appendix collects the ABNF grammar from the ABNF passages used | <t indent="0" pn="section-appendix.a-1">This appendix collects the ABNF gr | |||
ammar from the ABNF passages used | ||||
throughout the document.</t> | throughout the document.</t> | |||
<!-- Update the collected grammar files using `make sourcecode`, which --> | <t indent="0" pn="section-appendix.a-2"><xref target="jsonpath-abnf" forma | |||
<!-- is currently manual as it creates a little circular dependency. --> | t="default" sectionFormat="of" derivedContent="Figure 2"/> contains the collecte | |||
<!-- The filenames of the ::includes are likely to change when --> | d ABNF grammar that defines the | |||
<!-- kramdown-rfc-extract-sourcecode handles filenames better. --> | ||||
<t><xref target="jsonpath-abnf"/> contains the collected ABNF grammar that defin | ||||
es the | ||||
syntax of a JSONPath query.</t> | syntax of a JSONPath query.</t> | |||
<figure anchor="jsonpath-abnf"> | <figure anchor="jsonpath-abnf" align="left" suppress-title="false" pn="fig | |||
<name>Collected ABNF of JSONPath queries</name> | ure-2"> | |||
<sourcecode type="abnf"><![CDATA[ | <name slugifiedName="name-collected-abnf-of-jsonpath-">Collected ABNF of | |||
JSONPath Queries</name> | ||||
<sourcecode type="abnf" markers="false" pn="section-appendix.a-3.1"> | ||||
jsonpath-query = root-identifier segments | jsonpath-query = root-identifier segments | |||
segments = *(S segment) | segments = *(S segment) | |||
B = %x20 / ; Space | B = %x20 / ; Space | |||
%x09 / ; Horizontal tab | %x09 / ; Horizontal tab | |||
%x0A / ; Line feed or New line | %x0A / ; Line feed or New line | |||
%x0D ; Carriage return | %x0D ; Carriage return | |||
S = *B ; optional blank space | S = *B ; optional blank space | |||
root-identifier = "$" | root-identifier = "$" | |||
selector = name-selector / | selector = name-selector / | |||
wildcard-selector / | wildcard-selector / | |||
slice-selector / | slice-selector / | |||
index-selector / | index-selector / | |||
filter-selector | filter-selector | |||
name-selector = string-literal | name-selector = string-literal | |||
string-literal = %x22 *double-quoted %x22 / ; "string" | string-literal = %x22 *double-quoted %x22 / ; "string" | |||
%x27 *single-quoted %x27 ; 'string' | %x27 *single-quoted %x27 ; 'string' | |||
double-quoted = unescaped / | double-quoted = unescaped / | |||
%x27 / ; ' | %x27 / ; ' | |||
ESC %x22 / ; \" | ESC %x22 / ; \" | |||
ESC escapable | ESC escapable | |||
single-quoted = unescaped / | single-quoted = unescaped / | |||
%x22 / ; " | %x22 / ; " | |||
ESC %x27 / ; \' | ESC %x27 / ; \' | |||
ESC escapable | ESC escapable | |||
ESC = %x5C ; \ backslash | ESC = %x5C ; \ backslash | |||
unescaped = %x20-21 / ; see RFC 8259 | unescaped = %x20-21 / ; see RFC 8259 | |||
; omit 0x22 " | ; omit 0x22 " | |||
%x23-26 / | %x23-26 / | |||
; omit 0x27 ' | ; omit 0x27 ' | |||
%x28-5B / | %x28-5B / | |||
; omit 0x5C \ | ; omit 0x5C \ | |||
%x5D-D7FF / ; skip surrogate code points | %x5D-D7FF / | |||
; skip surrogate code points | ||||
%xE000-10FFFF | %xE000-10FFFF | |||
escapable = %x62 / ; b BS backspace U+0008 | escapable = %x62 / ; b BS backspace U+0008 | |||
%x66 / ; f FF form feed U+000C | %x66 / ; f FF form feed U+000C | |||
%x6E / ; n LF line feed U+000A | %x6E / ; n LF line feed U+000A | |||
%x72 / ; r CR carriage return U+000D | %x72 / ; r CR carriage return U+000D | |||
%x74 / ; t HT horizontal tab U+0009 | %x74 / ; t HT horizontal tab U+0009 | |||
"/" / ; / slash (solidus) U+002F | "/" / ; / slash (solidus) U+002F | |||
"\" / ; \ backslash (reverse solidus) U+005C | "\" / ; \ backslash (reverse solidus) U+005C | |||
(%x75 hexchar) ; uXXXX U+XXXX | (%x75 hexchar) ; uXXXX U+XXXX | |||
hexchar = non-surrogate / | hexchar = non-surrogate / | |||
(high-surrogate "\" %x75 low-surrogate) | (high-surrogate "\" %x75 low-surrogate) | |||
non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / | non-surrogate = ((DIGIT / "A"/"B"/"C" / "E"/"F") 3HEXDIG) / | |||
("D" %x30-37 2HEXDIG ) | ("D" %x30-37 2HEXDIG ) | |||
high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG | high-surrogate = "D" ("8"/"9"/"A"/"B") 2HEXDIG | |||
low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG | low-surrogate = "D" ("C"/"D"/"E"/"F") 2HEXDIG | |||
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | |||
wildcard-selector = "*" | wildcard-selector = "*" | |||
index-selector = int ; decimal integer | index-selector = int ; decimal integer | |||
int = "0" / | int = "0" / | |||
(["-"] DIGIT1 *DIGIT) ; - optional | (["-"] DIGIT1 *DIGIT) ; - optional | |||
DIGIT1 = %x31-39 ; 1-9 non-zero digit | DIGIT1 = %x31-39 ; 1-9 non-zero digit | |||
slice-selector = [start S] ":" S [end S] [":" [S step ]] | slice-selector = [start S] ":" S [end S] [":" [S step ]] | |||
start = int ; included in selection | start = int ; included in selection | |||
end = int ; not included in selection | end = int ; not included in selection | |||
step = int ; default: 1 | step = int ; default: 1 | |||
filter-selector = "?" S logical-expr | filter-selector = "?" S logical-expr | |||
logical-expr = logical-or-expr | logical-expr = logical-or-expr | |||
logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) | logical-or-expr = logical-and-expr *(S "||" S logical-and-expr) | |||
; disjunction | ; disjunction | |||
; binds less tightly than conjunction | ; binds less tightly than conjunction | |||
logical-and-expr = basic-expr *(S "&&" S basic-expr) | logical-and-expr = basic-expr *(S "&&" S basic-expr) | |||
; conjunction | ; conjunction | |||
; binds more tightly than disjunction | ; binds more tightly than disjunction | |||
basic-expr = paren-expr / | basic-expr = paren-expr / | |||
comparison-expr / | comparison-expr / | |||
test-expr | test-expr | |||
paren-expr = [logical-not-op S] "(" S logical-expr S ")" | paren-expr = [logical-not-op S] "(" S logical-expr S ")" | |||
; parenthesized expression | ; parenthesized expression | |||
logical-not-op = "!" ; logical NOT operator | logical-not-op = "!" ; logical NOT operator | |||
test-expr = [logical-not-op S] | test-expr = [logical-not-op S] | |||
(filter-query / ; existence/non-existence | (filter-query / ; existence/non-existence | |||
function-expr) ; LogicalType or NodesType | function-expr) ; LogicalType or NodesType | |||
filter-query = rel-query / jsonpath-query | filter-query = rel-query / jsonpath-query | |||
rel-query = current-node-identifier segments | rel-query = current-node-identifier segments | |||
current-node-identifier = "@" | current-node-identifier = "@" | |||
comparison-expr = comparable S comparison-op S comparable | comparison-expr = comparable S comparison-op S comparable | |||
literal = number / string-literal / | literal = number / string-literal / | |||
true / false / null | true / false / null | |||
comparable = literal / | comparable = literal / | |||
singular-query / ; singular query value | singular-query / ; singular query value | |||
function-expr ; ValueType | function-expr ; ValueType | |||
comparison-op = "==" / "!=" / | comparison-op = "==" / "!=" / | |||
"<=" / ">=" / | "<=" / ">=" / | |||
"<" / ">" | "<" / ">" | |||
singular-query = rel-singular-query / abs-singular-query | singular-query = rel-singular-query / abs-singular-query | |||
rel-singular-query = current-node-identifier singular-query-segments | rel-singular-query = current-node-identifier singular-query-segments | |||
abs-singular-query = root-identifier singular-query-segments | abs-singular-query = root-identifier singular-query-segments | |||
singular-query-segments = *(S (name-segment / index-segment)) | singular-query-segments = *(S (name-segment / index-segment)) | |||
name-segment = ("[" name-selector "]") / | name-segment = ("[" name-selector "]") / | |||
("." member-name-shorthand) | ("." member-name-shorthand) | |||
index-segment = "[" index-selector "]" | index-segment = "[" index-selector "]" | |||
number = (int / "-0") [ frac ] [ exp ] ; decimal number | number = (int / "-0") [ frac ] [ exp ] ; decimal number | |||
frac = "." 1*DIGIT ; decimal fraction | frac = "." 1*DIGIT ; decimal fraction | |||
skipping to change at line 3596 ¶ | skipping to change at line 3877 ¶ | |||
child-segment = bracketed-selection / | child-segment = bracketed-selection / | |||
("." | ("." | |||
(wildcard-selector / | (wildcard-selector / | |||
member-name-shorthand)) | member-name-shorthand)) | |||
bracketed-selection = "[" S selector *(S "," S selector) S "]" | bracketed-selection = "[" S selector *(S "," S selector) S "]" | |||
member-name-shorthand = name-first *name-char | member-name-shorthand = name-first *name-char | |||
name-first = ALPHA / | name-first = ALPHA / | |||
"_" / | "_" / | |||
%x80-D7FF / ; skip surrogate code points | %x80-D7FF / | |||
; skip surrogate code points | ||||
%xE000-10FFFF | %xE000-10FFFF | |||
name-char = DIGIT / name-first | name-char = name-first / DIGIT | |||
DIGIT = %x30-39 ; 0-9 | DIGIT = %x30-39 ; 0-9 | |||
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z | ALPHA = %x41-5A / %x61-7A ; A-Z / a-z | |||
descendant-segment = ".." (bracketed-selection / | descendant-segment = ".." (bracketed-selection / | |||
wildcard-selector / | wildcard-selector / | |||
member-name-shorthand) | member-name-shorthand) | |||
]]></sourcecode> | </sourcecode> | |||
</figure> | </figure> | |||
<t><xref target="normalized-path-abnf"/> contains the collected ABNF gramm | <t indent="0" pn="section-appendix.a-4"><xref target="normalized-path-abnf | |||
ar that | " format="default" sectionFormat="of" derivedContent="Figure 3"/> contains the c | |||
defines the syntax of a JSONPath Normalized Path, while also using the rules | ollected ABNF grammar that | |||
<tt>root-identifier</tt>, <tt>ESC</tt>, <tt>DIGIT</tt>, and <tt>DIGIT1</tt> from | defines the syntax of a JSONPath Normalized Path while also using the rules | |||
<xref target="jsonpath-abnf"/>.</t> | <tt>root-identifier</tt>, <tt>ESC</tt>, <tt>DIGIT</tt>, and <tt>DIGIT1</tt> from | |||
<figure anchor="normalized-path-abnf"> | <xref target="jsonpath-abnf" format="default" sectionFormat="of" derivedContent | |||
<name>Collected ABNF of JSONPath Normalized Paths</name> | ="Figure 2"/>.</t> | |||
<sourcecode type="abnf"><![CDATA[ | <figure anchor="normalized-path-abnf" align="left" suppress-title="false" | |||
pn="figure-3"> | ||||
<name slugifiedName="name-collected-abnf-of-jsonpath-n">Collected ABNF o | ||||
f JSONPath Normalized Paths</name> | ||||
<sourcecode type="abnf" markers="false" pn="section-appendix.a-5.1"> | ||||
normalized-path = root-identifier *(normal-index-segment) | normalized-path = root-identifier *(normal-index-segment) | |||
normal-index-segment = "[" normal-selector "]" | normal-index-segment = "[" normal-selector "]" | |||
normal-selector = normal-name-selector / normal-index-selector | normal-selector = normal-name-selector / normal-index-selector | |||
normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' | normal-name-selector = %x27 *normal-single-quoted %x27 ; 'string' | |||
normal-single-quoted = normal-unescaped / | normal-single-quoted = normal-unescaped / | |||
ESC normal-escapable | ESC normal-escapable | |||
normal-unescaped = ; omit %x0-1F control codes | normal-unescaped = ; omit %x0-1F control codes | |||
%x20-26 / | %x20-26 / | |||
; omit 0x27 ' | ; omit 0x27 ' | |||
%x28-5B / | %x28-5B / | |||
; omit 0x5C \ | ; omit 0x5C \ | |||
%x5D-D7FF / ; skip surrogate code points | %x5D-D7FF / | |||
; skip surrogate code points | ||||
%xE000-10FFFF | %xE000-10FFFF | |||
normal-escapable = %x62 / ; b BS backspace U+0008 | normal-escapable = %x62 / ; b BS backspace U+0008 | |||
%x66 / ; f FF form feed U+000C | %x66 / ; f FF form feed U+000C | |||
%x6E / ; n LF line feed U+000A | %x6E / ; n LF line feed U+000A | |||
%x72 / ; r CR carriage return U+000D | %x72 / ; r CR carriage return U+000D | |||
%x74 / ; t HT horizontal tab U+0009 | %x74 / ; t HT horizontal tab U+0009 | |||
"'" / ; ' apostrophe U+0027 | "'" / ; ' apostrophe U+0027 | |||
"\" / ; \ backslash (reverse solidus) U+005C | "\" / ; \ backslash (reverse solidus) U+005C | |||
(%x75 normal-hexchar) | (%x75 normal-hexchar) | |||
; certain values u00xx U+00XX | ; certain values u00xx U+00XX | |||
normal-hexchar = "0" "0" | normal-hexchar = "0" "0" | |||
( | ( | |||
("0" %x30-37) / ; "00"-"07" | ("0" %x30-37) / ; "00"-"07" | |||
; omit U+0008-U+000A BS HT LF | ; omit U+0008-U+000A BS HT LF | |||
("0" %x62) / ; "0b" | ("0" %x62) / ; "0b" | |||
; omit U+000C-U+000D FF CR | ; omit U+000C-U+000D FF CR | |||
("0" %x65-66) / ; "0e"-"0f" | ("0" %x65-66) / ; "0e"-"0f" | |||
("1" normal-HEXDIG) | ("1" normal-HEXDIG) | |||
) | ) | |||
normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" | normal-HEXDIG = DIGIT / %x61-66 ; "0"-"9", "a"-"f" | |||
normal-index-selector = "0" / (DIGIT1 *DIGIT) | normal-index-selector = "0" / (DIGIT1 *DIGIT) | |||
; non-negative decimal integer | ; non-negative decimal integer | |||
]]></sourcecode> | </sourcecode> | |||
</figure> | </figure> | |||
</section> | </section> | |||
<section anchor="inspired-by-xpath"> | <section anchor="inspired-by-xpath" numbered="true" removeInRFC="false" toc= | |||
<name>Inspired by XPath</name> | "include" pn="section-appendix.b"> | |||
<t>This appendix is informative.</t> | <name slugifiedName="name-inspired-by-xpath">Inspired by XPath</name> | |||
<t>At the time JSONPath was invented, XML was noted for the availability o | <t indent="0" pn="section-appendix.b-1">This appendix is informative.</t> | |||
f | <t indent="0" pn="section-appendix.b-2">At the time JSONPath was invented, | |||
powerful tools to analyze, transform and selectively extract data from | XML was noted for the availability of | |||
powerful tools to analyze, transform, and selectively extract data from | ||||
XML documents. | XML documents. | |||
<xref target="XPath"/> is one of these tools.</t> | <xref target="XPath" format="default" sectionFormat="of" derivedContent="XPath"/ | |||
<t>In 2007, the need for something solving the same class of problems for | > is one of these tools.</t> | |||
<t indent="0" pn="section-appendix.b-3">In 2007, the need for something so | ||||
lving the same class of problems for | ||||
the emerging JSON community became apparent, specifically for:</t> | the emerging JSON community became apparent, specifically for:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-app | |||
<li>Finding data interactively and extracting them out of <xref target=" | endix.b-4"> | |||
RFC8259"/> | <li pn="section-appendix.b-4.1">finding data interactively and extractin | |||
JSON values without special scripting.</li> | g them out of | |||
<li>Specifying the relevant parts of the JSON data in a request by a | JSON values <xref target="RFC8259" format="default" sectionFormat="of" derivedCo | |||
ntent="RFC8259"/> without special scripting and</li> | ||||
<li pn="section-appendix.b-4.2">specifying the relevant parts of the JSO | ||||
N data in a request by a | ||||
client, so the server can reduce the amount of data in its response, | client, so the server can reduce the amount of data in its response, | |||
minimizing bandwidth usage.</li> | minimizing bandwidth usage.</li> | |||
</ul> | </ul> | |||
<t>(Note: XPath has evolved since 2007, and recent versions even | <t indent="0" pn="section-appendix.b-5">(Note: XPath has evolved since 200 7, and recent versions even | |||
nominally support operating inside JSON values. | nominally support operating inside JSON values. | |||
This appendix only discusses the more widely used version of XPath | This appendix only discusses the more widely used version of XPath | |||
that was available in 2007.)</t> | that was available in 2007.)</t> | |||
<t>JSONPath picks up the overall feeling of XPath, but maps the concepts | <t indent="0" pn="section-appendix.b-6">JSONPath picks up the overall feel ing of XPath but maps the concepts | |||
to syntax (and partially semantics) that would be familiar to someone | to syntax (and partially semantics) that would be familiar to someone | |||
using JSON in a dynamic language.</t> | using JSON in a dynamic language.</t> | |||
<t>E.g., in popular dynamic programming languages such as JavaScript, | <t indent="0" pn="section-appendix.b-7">For example, in popular dynamic pr | |||
Python and PHP, the semantics of the XPath expression</t> | ogramming languages such as JavaScript, | |||
<sourcecode type="xpath"><![CDATA[ | Python, and PHP, the semantics of the XPath expression:</t> | |||
<sourcecode type="xpath" markers="false" pn="section-appendix.b-8"> | ||||
/store/book[1]/title | /store/book[1]/title | |||
]]></sourcecode> | </sourcecode> | |||
<t>can be realized in the expression</t> | <t indent="0" pn="section-appendix.b-9">can be realized in the expression: | |||
<sourcecode type="xpath"><![CDATA[ | </t> | |||
<sourcecode type="xpath" markers="false" pn="section-appendix.b-10"> | ||||
x.store.book[0].title | x.store.book[0].title | |||
]]></sourcecode> | </sourcecode> | |||
<t>or, in bracket notation,</t> | <t indent="0" pn="section-appendix.b-11">or in bracket notation:</t> | |||
<sourcecode type="xpath"><![CDATA[ | <sourcecode type="xpath" markers="false" pn="section-appendix.b-12"> | |||
x['store']['book'][0]['title'] | x['store']['book'][0]['title'] | |||
]]></sourcecode> | </sourcecode> | |||
<t>with the variable x holding the query argument.</t> | <t indent="0" pn="section-appendix.b-13">with the variable x holding the q | |||
<t>The JSONPath language was designed to:</t> | uery argument.</t> | |||
<ul spacing="normal"> | <t indent="0" pn="section-appendix.b-14">The JSONPath language was designe | |||
<li>be naturally based on those language characteristics;</li> | d to:</t> | |||
<li>cover only the most essential parts of XPath 1.0;</li> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-app | |||
<li>be lightweight in code size and memory consumption;</li> | endix.b-15"> | |||
<li>be runtime efficient.</li> | <li pn="section-appendix.b-15.1">be naturally based on those language ch | |||
aracteristics,</li> | ||||
<li pn="section-appendix.b-15.2">cover only the most essential parts of | ||||
XPath 1.0,</li> | ||||
<li pn="section-appendix.b-15.3">be lightweight in code size and memory | ||||
consumption, and</li> | ||||
<li pn="section-appendix.b-15.4">be runtime efficient.</li> | ||||
</ul> | </ul> | |||
<section anchor="xpath-overview"> | <section anchor="xpath-overview" numbered="true" removeInRFC="false" toc=" | |||
<name>JSONPath and XPath</name> | include" pn="section-appendix.b.1"> | |||
<t>JSONPath expressions apply to JSON values in the same way | <name slugifiedName="name-jsonpath-and-xpath">JSONPath and XPath</name> | |||
<t indent="0" pn="section-appendix.b.1-1">JSONPath expressions apply to | ||||
JSON values in the same way | ||||
as XPath expressions are used in combination with an XML document. | as XPath expressions are used in combination with an XML document. | |||
JSONPath uses <tt>$</tt> to refer to the root node of the query argument, simila r | JSONPath uses <tt>$</tt> to refer to the root node of the query argument, simila r | |||
to XPath's <tt>/</tt> at the front.</t> | to XPath's <tt>/</tt> at the front.</t> | |||
<t>JSONPath expressions move further down the hierarchy using <em>dot no tation</em> | <t indent="0" pn="section-appendix.b.1-2">JSONPath expressions move furt her down the hierarchy using <em>dot notation</em> | |||
(<tt>$.store.book[0].title</tt>) | (<tt>$.store.book[0].title</tt>) | |||
or the <em>bracket notation</em> | or the <em>bracket notation</em> | |||
(<tt>$['store']['book'][0]['title']</tt>), a lightweight/limited, and a more | (<tt>$['store']['book'][0]['title']</tt>); both replace XPath's <tt>/</tt> withi | |||
heavyweight syntax replacing XPath's <tt>/</tt> within query expressions.</t> | n query expressions, where <em>dot notation</em> serves as a lightweight but lim | |||
<t>Both JSONPath and XPath use <tt>*</tt> for a wildcard. | ited syntax while <em>bracket notation</em> is a | |||
The descendant operators, starting with <tt>..</tt>, borrowed from <xref target= | heavyweight but more general syntax.</t> | |||
"E4X"/>, are similar to XPath's <tt>//</tt>. | <t indent="0" pn="section-appendix.b.1-3">Both JSONPath and XPath use <t | |||
t>*</tt> for a wildcard. | ||||
JSONPath's descendant segment notation, starting with <tt>..</tt>, borrowed from | ||||
<xref target="E4X" format="default" sectionFormat="of" derivedContent="E4X"/>, | ||||
is similar to XPath's <tt>//</tt>. | ||||
The array slicing construct <tt>[start:end:step]</tt> is unique to JSONPath, | The array slicing construct <tt>[start:end:step]</tt> is unique to JSONPath, | |||
inspired by <xref target="SLICE"/> from ECMASCRIPT 4.</t> | inspired by <xref target="SLICE" format="default" sectionFormat="of" derivedCont | |||
<t>Filter expressions are supported via the syntax <tt>?<logical-expr | ent="SLICE"/> from ECMASCRIPT 4.</t> | |||
></tt> as in</t> | <t indent="0" pn="section-appendix.b.1-4">Filter expressions are support | |||
<sourcecode type="JSONPath"><![CDATA[ | ed via the syntax <tt>?<logical-expr></tt> as in:</t> | |||
$.store.book[?@.price < 10].title | <sourcecode type="application/jsonpath" markers="false" pn="section-appe | |||
]]></sourcecode> | ndix.b.1-5"> | |||
<t><xref target="tbl-xpath-overview"/> extends <xref target="tbl-overvie | $.store.book[?@.price < 10].title | |||
w"/> by providing a comparison | </sourcecode> | |||
<t indent="0" pn="section-appendix.b.1-6"><xref target="tbl-xpath-overvi | ||||
ew" format="default" sectionFormat="of" derivedContent="Table 20"/> extends <xre | ||||
f target="tbl-overview" format="default" sectionFormat="of" derivedContent="Tabl | ||||
e 1"/> by providing a comparison | ||||
with similar XPath concepts.</t> | with similar XPath concepts.</t> | |||
<table anchor="tbl-xpath-overview"> | <table anchor="tbl-xpath-overview" align="center" pn="table-20"> | |||
<name>XPath syntax compared to JSONPath</name> | <name slugifiedName="name-xpath-syntax-compared-to-js">XPath Syntax Co | |||
mpared to JSONPath</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">XPath</th> | <th align="left" colspan="1" rowspan="1">XPath</th> | |||
<th align="left">JSONPath</th> | <th align="left" colspan="1" rowspan="1">JSONPath</th> | |||
<th align="left">Description</th> | <th align="left" colspan="1" rowspan="1">Description</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>/</tt></td> | <tt>/</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$</tt></td> | <tt>$</tt></td> | |||
<td align="left">the root XML element</td> | <td align="left" colspan="1" rowspan="1">the root XML element</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>.</tt></td> | <tt>.</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>@</tt></td> | <tt>@</tt></td> | |||
<td align="left">the current XML element</td> | <td align="left" colspan="1" rowspan="1">the current XML element</ td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>/</tt></td> | <tt>/</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>.</tt> or <tt>[]</tt></td> | <tt>.</tt> or <tt>[]</tt></td> | |||
<td align="left">child operator</td> | <td align="left" colspan="1" rowspan="1">child operator</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>..</tt></td> | <tt>..</tt></td> | |||
<td align="left">n/a</td> | <td align="left" colspan="1" rowspan="1">n/a</td> | |||
<td align="left">parent operator</td> | <td align="left" colspan="1" rowspan="1">parent operator</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//</tt></td> | <tt>//</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>..name</tt>, <tt>..[index]</tt>, <tt>..*</tt>, or <tt>..[*]< | <tt>..name</tt>, <tt>..[index]</tt>, <tt>..*</tt>, or <tt>..[*] | |||
/tt></td> | </tt></td> | |||
<td align="left">descendants (JSONPath borrows this syntax from E4 | <td align="left" colspan="1" rowspan="1">descendants (JSONPath bor | |||
X)</td> | rows this syntax from E4X)</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>*</tt></td> | <tt>*</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>*</tt></td> | <tt>*</tt></td> | |||
<td align="left">wildcard: All XML elements regardless of their na mes</td> | <td align="left" colspan="1" rowspan="1">wildcard: All XML element s regardless of their names</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>@</tt></td> | <tt>@</tt></td> | |||
<td align="left">n/a</td> | <td align="left" colspan="1" rowspan="1">n/a</td> | |||
<td align="left">attribute access: JSON values do not have attribu | <td align="left" colspan="1" rowspan="1">attribute access: JSON va | |||
tes</td> | lues do not have attributes</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[]</tt></td> | <tt>[]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[]</tt></td> | <tt>[]</tt></td> | |||
<td align="left">subscript operator used to iterate over XML eleme nt collections and for predicates</td> | <td align="left" colspan="1" rowspan="1">subscript operator used t o iterate over XML element collections and for predicates</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>|</tt></td> | <tt>|</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[,]</tt></td> | <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 in dices, and slices</td> | <td align="left" colspan="1" rowspan="1">Union operator (results i n a combination of node sets); called list operator in JSONPath, allows combinin g member names, array indices, and slices</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">n/a</td> | <td align="left" colspan="1" rowspan="1">n/a</td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[start:end:step]</tt></td> | <tt>[start:end:step]</tt></td> | |||
<td align="left">array slice operator borrowed from ES4</td> | <td align="left" colspan="1" rowspan="1">array slice operator borr owed from ES4</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>[]</tt></td> | <tt>[]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>?</tt></td> | <tt>?</tt></td> | |||
<td align="left">applies a filter (script) expression</td> | <td align="left" colspan="1" rowspan="1">applies a filter (script) expression</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left">seamless</td> | <td align="left" colspan="1" rowspan="1">seamless</td> | |||
<td align="left">n/a</td> | <td align="left" colspan="1" rowspan="1">n/a</td> | |||
<td align="left">expression engine</td> | <td align="left" colspan="1" rowspan="1">expression engine</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>()</tt></td> | <tt>()</tt></td> | |||
<td align="left">n/a</td> | <td align="left" colspan="1" rowspan="1">n/a</td> | |||
<td align="left">grouping</td> | <td align="left" colspan="1" rowspan="1">grouping</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<!-- Note: the weirdness about the vertical bar above is intentional --> | <t indent="0" pn="section-appendix.b.1-8">For further illustration, <xre | |||
f target="tbl-xpath-equivalents" format="default" sectionFormat="of" derivedCont | ||||
<t>For further illustration, <xref target="tbl-xpath-equivalents"/> shows some X | ent="Table 21"/> shows some XPath expressions | |||
Path expressions | ||||
and their JSONPath equivalents.</t> | and their JSONPath equivalents.</t> | |||
<table anchor="tbl-xpath-equivalents"> | <table anchor="tbl-xpath-equivalents" align="center" pn="table-21"> | |||
<name>Example XPath expressions and their JSONPath equivalents</name> | <name slugifiedName="name-example-xpath-expressions-a">Example XPath E | |||
xpressions and Their JSONPath Equivalents</name> | ||||
<thead> | <thead> | |||
<tr> | <tr> | |||
<th align="left">XPath</th> | <th align="left" colspan="1" rowspan="1">XPath</th> | |||
<th align="left">JSONPath</th> | <th align="left" colspan="1" rowspan="1">JSONPath</th> | |||
<th align="left">Result</th> | <th align="left" colspan="1" rowspan="1">Result</th> | |||
</tr> | </tr> | |||
</thead> | </thead> | |||
<tbody> | <tbody> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>/store/book/author</tt></td> | <tt>/store/book/author</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$.store.book[*].author</tt></td> | <tt>$.store.book[*].author</tt></td> | |||
<td align="left">the authors of all books in the store</td> | <td align="left" colspan="1" rowspan="1">the authors of all books in the store</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//author</tt></td> | <tt>//author</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..author</tt></td> | <tt>$..author</tt></td> | |||
<td align="left">all authors</td> | <td align="left" colspan="1" rowspan="1">all authors</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>/store/*</tt></td> | <tt>/store/*</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$.store.*</tt></td> | <tt>$.store.*</tt></td> | |||
<td align="left">all things in store, which are some books and a r ed bicycle</td> | <td align="left" colspan="1" rowspan="1">all things in store, whic h are some books and a red bicycle</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>/store//price</tt></td> | <tt>/store//price</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$.store..price</tt></td> | <tt>$.store..price</tt></td> | |||
<td align="left">the prices of everything in the store</td> | <td align="left" colspan="1" rowspan="1">the prices of everything in the store</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//book[3]</tt></td> | <tt>//book[3]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[2]</tt></td> | <tt>$..book[2]</tt></td> | |||
<td align="left">the third book</td> | <td align="left" colspan="1" rowspan="1">the third book</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//book[last()]</tt></td> | <tt>//book[last()]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[-1]</tt></td> | <tt>$..book[-1]</tt></td> | |||
<td align="left">the last book in order</td> | <td align="left" colspan="1" rowspan="1">the last book in order</t d> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//book[position()<3]</tt></td> | <tt>//book[position()<3]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> | <tt>$..book[0,1]</tt><br/><tt>$..book[:2]</tt></td> | |||
<td align="left">the first two books</td> | <td align="left" colspan="1" rowspan="1">the first two books</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//book[isbn]</tt></td> | <tt>//book[isbn]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[?@.isbn]</tt></td> | <tt>$..book[?@.isbn]</tt></td> | |||
<td align="left">filter all books with isbn number</td> | <td align="left" colspan="1" rowspan="1">filter all books with an ISBN number</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//book[price<10]</tt></td> | <tt>//book[price<10]</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..book[?@.price<10]</tt></td> | <tt>$..book[?@.price<10]</tt></td> | |||
<td align="left">filter all books cheaper than 10</td> | <td align="left" colspan="1" rowspan="1">filter all books cheaper than 10</td> | |||
</tr> | </tr> | |||
<tr> | <tr> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>//*</tt></td> | <tt>//*</tt></td> | |||
<td align="left"> | <td align="left" colspan="1" rowspan="1"> | |||
<tt>$..*</tt></td> | <tt>$..*</tt></td> | |||
<td align="left">all elements in XML document; all member values a nd array elements contained in input value</td> | <td align="left" colspan="1" rowspan="1">all elements in an XML do cument; all member values and array elements contained in input value</td> | |||
</tr> | </tr> | |||
</tbody> | </tbody> | |||
</table> | </table> | |||
<t>XPath has a lot more functionality (location paths in unabbreviated s | <t indent="0" pn="section-appendix.b.1-10">XPath has a lot more function | |||
yntax, | ality (location paths in unabbreviated syntax, | |||
operators and functions) than listed in this comparison. Moreover, there are | operators, and functions) than listed in this comparison. Moreover, there are | |||
significant differences in how the subscript operator works in XPath and | significant differences in how the subscript operator works in XPath and | |||
JSONPath:</t> | JSONPath:</t> | |||
<ul spacing="normal"> | <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-a | |||
<li>Square brackets in XPath expressions always operate on the <em>nod | ppendix.b.1-11"> | |||
e | <li pn="section-appendix.b.1-11.1">Square brackets in XPath expression | |||
s always operate on the <em>node | ||||
set</em> resulting from the previous path fragment. Indices always start | set</em> resulting from the previous path fragment. Indices always start | |||
at 1.</li> | at 1.</li> | |||
<li>With JSONPath, square brackets operate on each of the nodes in the <em>nodelist</em> | <li pn="section-appendix.b.1-11.2">With JSONPath, square brackets oper ate on each of the nodes in the <em>nodelist</em> | |||
resulting from the previous query segment. Array indices always start | resulting from the previous query segment. Array indices always start | |||
at 0.</li> | at 0.</li> | |||
</ul> | </ul> | |||
</section> | </section> | |||
</section> | </section> | |||
<section anchor="json-pointer"> | <section anchor="json-pointer" numbered="true" removeInRFC="false" toc="incl | |||
<name>JSON Pointer</name> | ude" pn="section-appendix.c"> | |||
<t>This appendix is informative.</t> | <name slugifiedName="name-json-pointer">JSON Pointer</name> | |||
<t>JSONPath is not intended as a replacement for, but as a more powerful | <t indent="0" pn="section-appendix.c-1">This appendix is informative.</t> | |||
companion to, JSON Pointer <xref target="RFC6901"/>. The purposes of the two sta | <t indent="0" pn="section-appendix.c-2">In relation to JSON Pointer <xref | |||
ndards | target="RFC6901" format="default" sectionFormat="of" derivedContent="RFC6901"/>, | |||
JSONPath is not intended as a replacement but as a more powerful | ||||
companion. The purposes of the two standards | ||||
are different.</t> | are different.</t> | |||
<t>JSON Pointer is for identifying a single value within a JSON value whos e | <t indent="0" pn="section-appendix.c-3">JSON Pointer is for identifying a single value within a JSON value whose | |||
structure is known.</t> | structure is known.</t> | |||
<t>JSONPath can identify a single value within a JSON value, for example b y | <t indent="0" pn="section-appendix.c-4">JSONPath can identify a single val ue within a JSON value, for example, by | |||
using a Normalized Path. But JSONPath is also a query syntax that can be used | using a Normalized Path. But JSONPath is also a query syntax that can be used | |||
to search for and extract multiple values from JSON values whose structure | to search for and extract multiple values from JSON values whose structure | |||
is known only in a general way.</t> | is known only in a general way.</t> | |||
<t>A Normalized JSONPath can be converted into a JSON Pointer by convertin | <t indent="0" pn="section-appendix.c-5">A Normalized JSONPath can be conve | |||
g the syntax, | rted into a JSON Pointer by converting the syntax, | |||
without knowledge of any JSON value. The inverse is not generally true: a numeri | without knowledge of any JSON value. The inverse is not generally true, i.e., a | |||
c | numeric | |||
reference token (path component) in a JSON Pointer may identify a member value o f an object or an element of an array. | reference token (path component) in a JSON Pointer may identify a member value o f an object or an element of an array. | |||
For conversion to a JSONPath query, knowledge of the structure of the JSON value is | For conversion to a JSONPath query, knowledge of the structure of the JSON value is | |||
needed to distinguish these cases.</t> | needed to distinguish these cases.</t> | |||
</section> | </section> | |||
<section numbered="false" anchor="acknowledgements"> | <section numbered="false" anchor="acknowledgements" removeInRFC="false" toc= | |||
<name>Acknowledgements</name> | "include" pn="section-appendix.d"> | |||
<t>This document is based on <contact fullname="Stefan Gössner"/>'s | <name slugifiedName="name-acknowledgements">Acknowledgements</name> | |||
original online article defining JSONPath <xref target="JSONPath-orig"/>.</t> | <t indent="0" pn="section-appendix.d-1">This document is based on <contact | |||
<t>The books example was taken from | fullname="Stefan Gössner"/>'s | |||
http://coli.lili.uni-bielefeld.de/~andreas/Seminare/sommer02/books.xml | original online article defining JSONPath <xref target="JSONPath-orig" format="d | |||
— a dead link now.</t> | efault" sectionFormat="of" derivedContent="JSONPath-orig"/>.</t> | |||
<t>This work is indebted to Christoph Burgmer for the superb | <t indent="0" pn="section-appendix.d-2">The books example was taken from c | |||
JSONPath comparison project <xref target="COMPARISON"/> detailing the behavior o | ourse material that Bielefeld University, Germany used in 2002.</t> | |||
f over forty JSONPath | <t indent="0" pn="section-appendix.d-3">This work is indebted to <contact | |||
fullname="Christoph Burgmer"/> for the superb | ||||
JSONPath comparison project <xref target="COMPARISON" format="default" sectionFo | ||||
rmat="of" derivedContent="COMPARISON"/> that details the behavior of over forty | ||||
JSONPath | ||||
implementations applied to numerous queries.</t> | implementations applied to numerous queries.</t> | |||
<!-- LocalWords: JSONPath XPath nodelist memoization | </section> | |||
--> | <section anchor="contributors" numbered="false" toc="include" removeInRFC="f | |||
alse" pn="section-appendix.e"> | ||||
</section> | <name slugifiedName="name-contributors">Contributors</name> | |||
<section anchor="contributors" numbered="false" toc="include" removeInRFC="f | ||||
alse"> | ||||
<name>Contributors</name> | ||||
<contact initials="M." surname="Mikulicic" fullname="Marko Mikulicic"> | <contact initials="M." surname="Mikulicic" fullname="Marko Mikulicic"> | |||
<organization>InfluxData, Inc.</organization> | <organization showOnFrontPage="true">InfluxData, Inc.</organization> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<city>Pisa</city> | <city>Pisa</city> | |||
<country>IT</country> | <country>Italy</country> | |||
</postal> | </postal> | |||
<email>mmikulicic@gmail.com</email> | <email>mmikulicic@gmail.com</email> | |||
</address> | </address> | |||
</contact> | </contact> | |||
<contact initials="E." surname="Surov" fullname="Edward Surov"> | <contact initials="E." surname="Surov" fullname="Edward Surov"> | |||
<organization>TheSoul Publishing Ltd.</organization> | <organization showOnFrontPage="true">TheSoul Publishing Ltd.</organizati on> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<city>Limassol</city> | <city>Limassol</city> | |||
<country>Cyprus</country> | <country>Cyprus</country> | |||
</postal> | </postal> | |||
<email>esurov.tsp@gmail.com</email> | <email>esurov.tsp@gmail.com</email> | |||
</address> | </address> | |||
</contact> | </contact> | |||
<contact initials="G." surname="Dennis" fullname="Greg Dennis"> | <contact initials="G." surname="Dennis" fullname="Greg Dennis"> | |||
<organization/> | <organization showOnFrontPage="true"/> | |||
<address> | <address> | |||
<postal> | <postal> | |||
<city>Auckland</city> | <city>Auckland</city> | |||
<country>New Zealand</country> | <country>New Zealand</country> | |||
</postal> | </postal> | |||
<email>gregsdennis@yahoo.com</email> | <email>gregsdennis@yahoo.com</email> | |||
<uri>https://github.com/gregsdennis</uri> | <uri>https://github.com/gregsdennis</uri> | |||
</address> | </address> | |||
</contact> | </contact> | |||
</section> | </section> | |||
<section anchor="authors-addresses" numbered="false" removeInRFC="false" toc | ||||
="include" pn="section-appendix.f"> | ||||
<name slugifiedName="name-authors-addresses">Authors' Addresses</name> | ||||
<author initials="S." surname="Gössner" fullname="Stefan Gössner" role="ed | ||||
itor"> | ||||
<organization showOnFrontPage="true">Fachhochschule Dortmund</organizati | ||||
on> | ||||
<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 showOnFrontPage="true"/> | ||||
<address> | ||||
<postal> | ||||
<street/> | ||||
<city>Winchester</city> | ||||
<region/> | ||||
<code/> | ||||
<country>United Kingdom</country> | ||||
</postal> | ||||
<phone/> | ||||
<email>glyn.normington@gmail.com</email> | ||||
</address> | ||||
</author> | ||||
<author initials="C." surname="Bormann" fullname="Carsten Bormann" role="e | ||||
ditor"> | ||||
<organization showOnFrontPage="true">Universität Bremen TZI</organizatio | ||||
n> | ||||
<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> | ||||
</section> | ||||
</back> | </back> | |||
<!-- ##markdown-source: | ||||
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 | ||||
AA== | ||||
</rfc> | </rfc> | |||
End of changes. 935 change blocks. | ||||
3017 lines changed or deleted | 3319 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. |