Draft: draft-ietf-jsonpath-base

Commentary: This is a full rebase of branch  ( ) on current main . 
 Does this incorporate any changes from the discussions from , or is it a simple rebase ? 
 It is a simple rebase , followed by a number of edits coming from the discussions here . Most of the remaining conversations need some further discussion , so I hope to cover them with my updated slides in a couple of hours . 
 Looks like a good next step on our path .
Paragraph (version A):
The terminology of RFC8259 applies except where clarified below.
Definitions for "Object", "Array", and "Number" remain unchanged.
Importantly "object" and "array" in particular do not take on a
generic meaning, such as they would in a general programming context.
Paragraph (version B):
The terminology of RFC8259 applies except where clarified below.  The
terms "Primitive" and "Structured" are used to group the types as in
Section 1 of RFC8259.  Definitions for "Object", "Array", "Number",
and "String" remain unchanged.  Importantly "object" and "array" in
particular do not take on a generic meaning, such as they would in a
general programming context.
Paragraph (version A):
for paths input to a JSONPath processor.  [1] Where a JSONPath
processor uses JSONPath expressions as output paths, these will
always be converted to Output Paths which employ the more general
_bracket-notation_.  [2] Bracket notation is more general than dot
notation and can serve as a canonical form when a JSONPath processor
uses JSONPath expressions as output paths.
Paragraph (version B):
for paths input to a JSONPath processor.  [1] Where a JSONPath
processor uses JSONPath expressions as output paths, these will
always be converted to Output Paths which employ the more general
_bracket notation_.  [2] Bracket notation is more general than dot
notation and can serve as a canonical form when a JSONPath processor
uses JSONPath expressions as output paths.
Paragraph (version A):
Next, ".a" selects from any input node of type object and selects any
value of the input node corresponding to the member name ""a"".  The
result is again a list of one node: "[{"b":0},{"b":1},{"c":2}]".
Paragraph (version A):
Finally, ".b" selects from any input node of type object with a
member name "b" and selects the value of the input node corresponding
to that name.  The result is a list containing "0", "1".  This is the
concatenation of three lists, two of length one containing "0", "1",
respectively, and one of length zero.
Paragraph (version B):
Next, ".a" selects from any input node of type object and selects the
node of any member value of the input node corresponding to the
member name ""a"".  The result is again a list of one node:
"[{"b":0},{"b":1},{"c":2}]".
Paragraph (version B):
Finally, ".b" selects from any input node of type object with a
member name "b" and selects the node of the member value of the input
node corresponding to that name.  The result is a list containing
"0", "1".  This is the concatenation of three lists, two of length
one containing "0", "1", respectively, and one of length zero.
Paragraph (version A):
A dot child selector has a member name known as a dot child name or a
single asterisk ("*").
Paragraph (version A):
A dot child name corresponds to a name in a object.
Paragraph (version A):
More general child names, such as the empty string, are supported by
"Union Child" (unionchild).
Paragraph (version A):
Note that the "dot-child-name" rule follows the philosophy of JSON
strings and is allowed to contain bit sequences that cannot encode
Unicode characters (a single unpaired UTF-16 surrogate, for example).
The behaviour of an implementation is undefined for child names which
do not encode Unicode characters.
Paragraph (version A):
A dot child name which is not a single asterisk ("*") is considered
to have a member name.  It selects the value corresponding to the
name from any object node.  It selects no nodes from a node which is
not a object.
Paragraph (version A):
The member name of a dot child name is the sequence of Unicode
characters contained in that name.
Paragraph (version A):
A dot child name consisting of a single asterisk is a wild card.  It
selects all the values of any object node.  It also selects all the
elements of any array node.  It selects no nodes from number, string,
or literal nodes.
Paragraph (version A):
A union selector consists of one or more union elements.
Paragraph (version A):
A union selects any node which is selected by at least one of the
union selectors and selects the concatenation of the lists (in the
order of the selectors) of nodes selected by the union elements.
Paragraph (version A):
A child is a quoted string.
Paragraph (version A):
Notes: 1. double-quoted strings follow JSON in RFC8259.  Single-
quoted strings follow an analogous pattern.  2.  "HEXDIG" includes
A-F and a-f.
Paragraph (version A):
The child selects the value corresponding to the member name from any
object node that has a member with that name.  It selects no nodes
from a node which is not a object.
Paragraph (version A):
An array selector selects zero or more elements of an array node.  An
array selector takes the form of an index, which selects at most one
element, or a slice, which selects zero or more elements.
Paragraph (version A):
An array index is an integer (in base 10).
Paragraph (version A):
Note: the syntax does not allow integers with leading zeros such as
"01" and "-01".
Paragraph (version A):
An array slice consists of three optional integers (in base 10)
separated by colons.
Paragraph (version A):
Note: the array slices ":" and "::" are both syntactically valid, as
are ":2:2", "2::2", and "2:4:".
Paragraph (version B):
Dot selector ".<name>", used with object member names exclusively.
Paragraph (version B):
Dot wild card selector ".*".
Paragraph (version B):
Index selector "[<index>]", where "<index>" is either an (possibly
negative) array index or an object member name.
Paragraph (version B):
Index wild card selector "[*]".
Paragraph (version B):
Array slice selector "[<start>:<end>:<step>]", where "<start>",
"<end>", "<step>" are integer literals.
Paragraph (version B):
Nested descendants selector "..".
Paragraph (version B):
Union selector "[<sel1>,<sel2>,...,<selN>]", holding a comma
delimited list of index, index wild card, array slice, and filter
selectors.
Paragraph (version B):
Every valid JSONPath query MUST begin with the root selector "$".
Paragraph (version B):
The Argument -- the root JSON value -- becomes the root node, which
is addressed by the root selector "$".
Paragraph (version B):
A dot selector starts with a dot "." followed by an object's member
name.
Paragraph (version B):
The "dot-selector" selects the node of the member value corresponding
to the member name from any JSON object.  It selects no nodes from
any other JSON value.
Paragraph (version B):
Note that the "dot-selector" follows the philosophy of JSON strings
and is allowed to contain bit sequences that cannot encode Unicode
characters (a single unpaired UTF-16 surrogate, for example).  The
behaviour of an implementation is undefined for member names which do
not encode Unicode characters.
Paragraph (version B):
The dot wild card selector has the form ".*".
Paragraph (version B):
A "dot-wild-selector" acts as a wild card by selecting the nodes of
all member values of an object as well as all element nodes of an
array.  Applying the "dot-wild-selector" to a primitive JSON value
(number, string, or true/false/null) selects no node.
Paragraph (version B):
An index selector "[<index>]" addresses at most one object member
value or at most one array element value.
Paragraph (version B):
Applying the "index-selector" to an object value, a "quoted-member-
name" string is required.  JSONPath allows it to be enclosed in
_single_ or _double_ quotes.
Paragraph (version B):
Applying the "index-selector" to an array, a numerical "element-
index" is required.  JSONPath allows it to be negative.
Paragraph (version B):
Notes: 1. "double-quoted" strings follow JSON in RFC8259; "single-
quoted" strings follow an analogous pattern.  2.  An "element-index"
is an integer (in base 10, as in JSON numbers).  3.  As in JSON
numbers, the syntax does not allow octal-like integers with leading
zeros such as "01" or "-01".
Paragraph (version B):
The "index-selector" applied with a "quoted-member-name" to an object
selects the node of the corresponding member value from it, if and
only if that object has a member with that name.  Nothing is selected
from a value which is not a object.
Paragraph (version B):
Array indexing via "element-index" is a way of selecting a particular
array element using a zero-based index.  For example, selector "[0]"
selects the first and selector "[4]" the fifth element of a
sufficiently long array.
Paragraph (version B):
A negative "element-index" counts from the array end.  For example,
selector "[-1]" selects the last and selector "[-2]" selects the last
but one element of an array with at least two elements.
Paragraph (version B):
The index wild card selector has the form "[*]".
Paragraph (version B):
An "index-wild-selector" selects the nodes of all member values of an
object as well as of all elements of an array.  Applying the "index-
wild-selector" to a primitive JSON value (such as a number, string,
or true/false/null) selects no node.
Paragraph (version B):
The "index-wild-selector" behaves identically to the "dot-wild-
selector".
Paragraph (version B):
The array slice selector has the form "[<start>:<end>:<step>]".  It
selects elements starting at index "<start>", ending at -- but not
including -- "<end>", while incrementing by "step".
Paragraph (version B):
The "slice-selector" consists of three optional decimal integers
separated by colons.
Paragraph (version B):
The "slice-selector" was inspired by the slice operator of ECMAScript
4 (ES4), which was deprecated in 2014, and that of Python.
Paragraph (version B):
The descendant selector starts with a double dot ".." and can be
followed by an object member name (similar to the "dot-selector"), by
an "index-selector" acting on objects or arrays, or by a wild card.
Paragraph (version B):
The "descendant-selector" is inspired by ECMAScript for XML (E4X).
It selects the node and all its descendants.
Paragraph (version B):
The union selector is syntactically related to the "index-selector".
It contains multiple, comma separated entries.
Paragraph (version B):
Task (T1): This, besides slice-index, is currently one of only two
places in the document that mentions whitespace.  Whitespace needs
to be handled throughout the ABNF syntax.  Room Consensus at the
2021-06-15 interim was that JSONPath generally is generous with
allowing insignificant whitespace throughout.  Minimizing the
impact of the many whitespace insertion points by choosing a rule
name such as "S" was mentioned.  Some conventions will probably
help with minimizing the number of places where S needs to be
inserted.
Paragraph (version B):
A union selects any node which is selected by at least one of the
union selectors and selects the concatenation of the lists (in the
order of the selectors) of nodes selected by the union elements.
Note that any node selected in more than one of the union selectors
is kept as many times in the node list.
Paragraph (version B):
The filter selector has the form "[?<expr>]".  It works via iterating
over structured values, i.e. arrays and objects.
Paragraph (version B):
During iteration process each array element or object member is
visited and its value -- accessible via symbol "@" -- or one of its
descendants -- uniquely defined by a relative path -- is tested
against a boolean expression "boolean-expr".
Paragraph (version B):
The current item is selected if and only if the result is "true".
Paragraph (version B):
Parentheses can be used with "boolean-expr" for grouping.  So
filter selection syntax in the original proposal "[?(<expr>)]" is
naturally contained in the current lean syntax "[?<expr>]" as a
special case.
Paragraph (version B):
Comparisons are restricted to primitive values (such as number,
string, "true", "false", "null").  Comparisons with complex values
will fail, i.e. no selection occurs.
Paragraph (version B):
Types are not implicitly converted in comparisons.  So ""13 ==
'13'"" selects no node.
Paragraph (version B):
A member or element value by itself is _falsy_ only, if it does
not exist.  Otherwise it is _truthy_, resulting in its value.  To
be more specific explicit comparisons are necessary.  This
existence test -- as an exception of the general rule -- also
works with complex values.
Paragraph (version B):
Regular expression tests can be applied to "string" values only.
Paragraph (version B):
Containment tests work with arrays and objects.
Paragraph (version B):
Explicit boolean type conversion is done by the not operator "neg-
op".
Paragraph (version B):
The behaviour of operators is consistent with the 'C'-family of
programming languages.
Paragraph (version B):
The "filter-selector" works with arrays and objects exclusively.  Its
result might be a list of _zero_, _one_, _multiple_ or _all_ of their
element or member values then.  Applied to other value types, it will
select nothing.
Paragraph (version B):
Negation operator "neg-op" allows to test _falsiness_ of values.
Paragraph (version B):
Applying negation operator twice "!!" gives us _truthiness_ of
values.
Paragraph (version B):
Task (T2): Separate out expression language.  For now, this
section is a repository for ABNF taken from RFC8259.  This needs
to be deduplicated with definitions above.