)-1]. <del> Strings on the right-hand side of the "=~" regex matching operator MUST conform to I-D.draft-ietf-jsonpath-iregexp. </del> The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further errors relating to the well-formedness and the validity of a JSONPath "true", "false", and "null" are lower-case only (case-sensitive). <del> The syntax of regular expressions in the string-literals on the right-hand side of "=~" is as defined in I-D.draft-ietf-jsonpath- iregexp. </del> The following table lists filter expression operators in order of precedence from highest (binds most tightly) to lowest (binds least tightly). 2.5.5.2.3. <del> A regular-expression test yields true if and only if the value on the left-hand side of "=~" is a string value and it matches the regular expression on the right-hand side according to the semantics of I- D.draft-ietf-jsonpath-iregexp. The semantics of regular expressions are as defined in I-D.draft- ietf-jsonpath-iregexp. </del>  2.5.5.2.4. <del> The logical AND, OR, and NOT operators have the normal semantics of Boolean algebra and obey its laws (see, for example, BOOLEAN-LAWS). </del>  2.5.5.3. depth N in the input value. There are two kinds of segment: child segments and descendant <del> segments.  ~~~~ abnf segment = child-segment / descendant-segment ~~~~ </del>  The syntax and semantics of each kind of segment are defined below. Person & email address to contact for further information: iesg@ietf.org  4. Security considerations for JSONPath can stem from Other attacks can target the behavior of underlying technologies such as UTF-8 (see RFC3629) and the Unicode character set.

Weirdly, I cannot reply to this observation: URL Expiry is somewhat unusual for IANA registries (early allocations do expire). What is the behavior you would expect implementations to exhibit? The function extension to stop working on the expiry day?
Hey NAME based on this useful-looking discussion, do you plan to revise this significantly? I'm wondering if I should give it a careful read now or wait for an updated version.
Definitely. Of course, I'd like to have your input on the points raised (the non-trivial ones). We might even want to have a design-team meeting...
Might be a good idea to mark the non-non-trivial issues above resolved, to help reviewer focus. If it's OK, I'll wait for the next revision to go end-to-end. Agreed on a design meeting.
Here's my list of items where we could use input: More frugal with allowing whitespace? return value of functions that don't get the right arguments (e.g., length(1)) (interaction with -- non-singular paths in exist-expr) IANA designated expert instructions (frugal with "good" names) expiring reservations? (shades of certificates) domain of length (arrays now, add strings, objects?)? should there be another function for the size of nodelists (size())? Probably mostly resolved: for function names (ASCII, lowercase, only)
NAME I rebased this and resolved some conflicts.
Update: Address whitespace in a separate PR, if desired. Semantic issue: What to do with value of wrong kind? Fixed in 08dd7ad Fixed in afda44a Probably not. Semantic issue: What to do with value of wrong kind? Yes, that is called count() now (e3a565a) Let's stick with that name space.
We may be able to make this syntactically invalid. See URL for some ideas.

)-1].  The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further errors relating to the well-formedness and the validity of a JSONPath "true", "false", and "null" are lower-case only (case-sensitive).  The following table lists filter expression operators in order of precedence from highest (binds most tightly) to lowest (binds least tightly). 2.5.5.2.3.  <ins> The logical AND, OR, and NOT operators have the normal semantics of Boolean algebra and obey its laws (see, for example, BOOLEAN-LAWS). </ins> 2.5.5.2.4.  <ins> [unnumbered-bad] Beyond the filter expression functionality defined in the preceding subsections, JSONPath defines an extension point that can be used to add filter expression functionality: "Function Extensions". A function extension defines a registered name (see iana-fnex) that can be applied to a sequence of zero or more arguments, resulting in a result.  A function-expression stands for ("returns") a nodelist or a value.  The arguments are filter expressions that are to be interpreted as nodelists or values.  For each argument and for the result, the function extension defines the "kind" of the item, i.e., whether the item is a value or a nodelist ("nodes"). Syntactically, a function-expression can occur anywhere where a singular-path can occur (exist-expr, comparable).  A function- expression that employs a function extension that returns a nodelist MUST return a singular node to be used in a comparable. 2.5.5.2.4.1. The "length" function extension provides a way to compute the length of a value and make that available for further processing in the filter expression: Its only argument is a value (possibly taken from a singular path as in the example above).  The result also is a value, an unsigned integer. If the argument value is a string, the result is the number of Unicode scalar values in the string. If the argument value is an array, the result is the number of elements in the array. If the argument value is an object, the result is the number of members in the object. For any other argument value, the result is one. 2.5.5.2.4.2. The "count" function extension provides a way to obtain the number of nodes in a nodelist and make that available for further processing in the filter expression: Its only argument is a nodelist.  The result is a value, an unsigned integer, that gives the number of nodes in the nodelist.  Note that there is no deduplication of the nodelist. [dedup] 2.5.5.2.4.3. The "match" function extension provides a way to check whether (the entirety of, see search below) a given string matches a given regular expression, which is in I-D.draft-ietf-jsonpath-iregexp form. Its first argument is a string that is matched against the iregexp contained in the string that is the second argument.  The result is "true" if the string matches the iregexp and "false" otherwise. 2.5.5.2.4.4. The "search" function extension provides a way to check whether a given string contains a substring that matches a given regular expression, which is in I-D.draft-ietf-jsonpath-iregexp form. Its first argument is a string that is searched for at least one substring that matches the iregexp contained in the string that is the second argument.  The result is "true" if such a substring exists, "false" otherwise. o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o </ins> 2.5.5.3. depth N in the input value. There are two kinds of segment: child segments and descendant  <ins> segments. </ins> The syntax and semantics of each kind of segment are defined below. Person & email address to contact for further information: iesg@ietf.org <ins> 3.2. This specification defines a new "Function Extensions sub-registry" in a new "JSONPath Parameters registry", with the policy "expert review" (BCP26). The experts are instructed to be frugal in the allocation of function extension names that are suggestive of generally applicable semantics, keeping them in reserve for functions that are likely to enjoy wide use and can make good use of their conciseness.  The expert is also instructed to direct the registrant to provide a specification (BCP26), but can make exceptions, for instance when a specification is not available at the time of registration but is likely forthcoming.  If the expert becomes aware of function extensions that are deployed and in use, they may also initiate a registration on their own if they deem such a registration can avert potential future collisions. Each entry in the registry must include: Initial entries in this sub-registry are as listed in pre-reg: </ins> 4. Security considerations for JSONPath can stem from Other attacks can target the behavior of underlying technologies such as UTF-8 (see RFC3629) and the Unicode character set. <ins> Editorial Comments [unnumbered-bad] -- cabo: This should not be an unnumbered section, which it is forced to be by the parent section being unnumbered too.  The overall structure where the parts of this subsection go to needs to be decided; one part already is in the IANA Considerations in [dedup] Well, that can be discussed. </ins>


Abstract <del> JSONPath defines a string syntax for selecting and extracting values within a JSON (RFC 8259) value. </del>  1. JSON RFC8259 is a popular representation format for structured data <del> values.  JSONPath defines a string syntax for identifying values within a JSON value. </del>  JSONPath is not intended as a replacement for, but as a more powerful companion to, JSON Pointer RFC6901.  See json-pointer.

This is an attempt to make two sentences in the abstract and introduction less clunky while not jettisoning their precision.
Thanks NAME I see you managed to approve a draft PR - interesting.
Works for me, although one would need to understand that JSON values are nested to understand the abstract. (But we can't start from the creation of the universe.)

Abstract  <ins> JSONPath defines a string syntax for selecting and extracting JSON (RFC 8259) values from a JSON value. </ins> 1. JSON RFC8259 is a popular representation format for structured data  <ins> values.  JSONPath defines a string syntax for selecting and extracting JSON values from a JSON value. </ins> JSONPath is not intended as a replacement for, but as a more powerful companion to, JSON Pointer RFC6901.  See json-pointer.


empty nodelist is a valid query result. A segment performs its function on each of the nodes in its input <del> nodelist.  During such a function execution, each such node is referred to as the "current node".  Each of these function executions produces a nodelist, which are then concatenated to produce the result of the segment.  A node may be selected more than once and appears that number of times in the nodelist.  Duplicate nodes are not removed. </del>  A syntactically valid segment MUST NOT produce errors when executing the query.  This means that some operations that might be considered

Fixes URL
I left that in deliberately. We have removed the colliding term and we are now free to use current node () throughout. I will follow up with a PR which does just that. I objected to the term "function" in this context previously. I'll follow up with a PR to delete it, which will leave it free for function extensions.
The term "current node" is traditionally used with iterating over children of structured nodes in filter selectors. Now it also appears in 3.3 Semantics chapter in a different context: To avoid confusion of readers, we might use a different term there. A good alternative would be "context node", which is also used by XPath in a similar context.
Perhaps a simple solution would be to avoid the use of the term in 3.3 as this term doesn't appear to be used elsewhere.
Please see the simplification in URL
Note that there is still an instance of "current node identifier" in table 1. I also note that then English usage of "function" now collides with the term we coin in the function extensions. But the basic change here is right, so I approve.

empty nodelist is a valid query result. A segment performs its function on each of the nodes in its input  <ins> nodelist.  Each of these function executions produces a nodelist, which are then concatenated to produce the result of the segment.  A node may be selected more than once and appears that number of times in the nodelist.  Duplicate nodes are not removed. </ins> A syntactically valid segment MUST NOT produce errors when executing the query.  This means that some operations that might be considered


3.5.5.1. <del> The filter selector has the form "?<expr>".  It works via iterating over structured values, i.e. arrays and objects. </del>  <del> During the 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". The current item is selected if and only if the boolean expression yields true. </del>  Paths in filter expressions are Singular Paths, each of which selects at most one node.  Parentheses MAY be used within "boolean-expr" for grouping. Comparisons are restricted to Singular Path values and primitive nodelist is not stipulated, since JSON objects are unordered. Children of an array appear in array order in the resultant nodelist. <del> A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the array or object. </del> 3.5.5.2.1. A singular path by itself in a Boolean context is an existence test

There may be some more shake-out as filter semantics are scattered through the syntax section. We may need to live with this because it makes more sense to talk about semantics in the context of each particular piece of syntax. But let's use the current PR just to use the current node term consistently.

3.5.5.1.  <ins> The filter selector has the form "?<expr>".  It iterates over structured values, i.e., arrays and objects. </ins>  <ins> During the iteration process the node of each array element or object member being visited is known as the current node.  A boolean expression, usually involving the current node, is evaluated and the current node is selected if and only if the expression yields true. </ins> Paths in filter expressions are Singular Paths, each of which selects at most one node. <ins> The current node is accessible via the current node identifier "@". </ins> Parentheses MAY be used within "boolean-expr" for grouping. Comparisons are restricted to Singular Path values and primitive nodelist is not stipulated, since JSON objects are unordered. Children of an array appear in array order in the resultant nodelist.  3.5.5.2.1. A singular path by itself in a Boolean context is an existence test


in ABNF as "%x2318". The terminology of RFC8259 applies except where clarified below.  The <del> terms "Primitive" and "Structured" are used to group the types as in RFC8259; JSON Objects and Arrays are structured, all other types are primitive.  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. </del>  Additional terms used in this specification are defined below. Firstly, "$" produces a nodelist consisting of just the argument. <del> 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: </del>  "[{"b":0},{"b":1},{"c":2}]". <del> Next, "[*]" selects from an input node of type array all its elements (if the input node were of type object, it would select all its member values, but not the member names).  The result is a list of three nodes: "{"b":0}", "{"b":1}", and "{"c":2}". </del>  <del> 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. </del>  As a consequence of this approach, if any of the segments produces an empty nodelist, then the whole query produces an empty nodelist. orderings in successive runs of the query. In what follows, the semantics of each segment are defined for each <del> type of input node. </del>  3.4. or of their array elements or member values, respectively.  Applied to <del> other value types, it will select nothing. </del>  The order in which the children of an object appear in the resultant nodelist is not stipulated, since JSON objects are unordered. a comparison using the operator "==" yields true if and only if the comparison is between: <del> values of the same primitive type (numbers, strings, booleans, and "null") which are equal, </del>  equal arrays, that is arrays of the same length where each element of the first array is equal to the corresponding by the objects are equal. a comparison using the operator "<" yields true if and only if the <del> comparison is between values of the same type which are both numbers or both strings and which satisfy the comparison: </del>  numbers expected to interoperate as per RFC7493 MUST compare using the normal mathematical ordering; numbers not expected to

JSON types are not used much in the JSON spec. It is debatable whether there really is a boolean type or simply the values and . Also, the JSONPath spec doesn't really benefit from this term.
I think this reads well without breaking any semantics.

in ABNF as "%x2318". The terminology of RFC8259 applies except where clarified below.  The  <ins> terms "Primitive" and "Structured" are used to group different kinds of values as in RFC8259; JSON Objects and Arrays are structured, all other values are primitive.  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. </ins> Additional terms used in this specification are defined below. Firstly, "$" produces a nodelist consisting of just the argument.  <ins> Next, ".a" selects from any object input node 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: </ins> "[{"b":0},{"b":1},{"c":2}]".  <ins> Next, "[*]" selects from any array input node all its elements (for an object input node, it would select all its member values, but not the member names).  The result is a list of three nodes: "{"b":0}", "{"b":1}", and "{"c":2}". </ins>  <ins> Finally, ".b" selects from any object input node 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. </ins> As a consequence of this approach, if any of the segments produces an empty nodelist, then the whole query produces an empty nodelist. orderings in successive runs of the query. In what follows, the semantics of each segment are defined for each  <ins> kind of input node. </ins> 3.4. or of their array elements or member values, respectively.  Applied to  <ins> primitive values, it will select nothing. </ins> The order in which the children of an object appear in the resultant nodelist is not stipulated, since JSON objects are unordered. a comparison using the operator "==" yields true if and only if the comparison is between:  <ins> equal primitive values, </ins> equal arrays, that is arrays of the same length where each element of the first array is equal to the corresponding by the objects are equal. a comparison using the operator "<" yields true if and only if the  <ins> comparison is between values which are both numbers or both strings and which satisfy the comparison: </ins> numbers expected to interoperate as per RFC7493 MUST compare using the normal mathematical ordering; numbers not expected to


3.5.4.2.1. <del> This section is non-normative. </del>  Array slicing is inspired by the behavior of the "Array.prototype.slice" method of the JavaScript language as defined

Non-normative may be a better option, throughout, because surely normative sections are informative too? NAME WDYT?
Given we use Informative for the non-normative references, I guess we should do the same throughout. Hopefully no-one will misunderstand...

3.5.4.2.1.  <ins> This section is informative. </ins> Array slicing is inspired by the behavior of the "Array.prototype.slice" method of the JavaScript language as defined


1.3.  A JSONPath expression is applied to a JSON value, the .  The output is a nodelist. of zero or more segments each of which contains one or more selectors. <del> 1.3.1. </del>  The in the context of the evaluation of a filter expression (described later). <del> 1.3.2. </del>  Segments can use the various shorthands in terms of bracket notation.  Examples and descriptions use shorthands where convenient. <del> 1.3.3. </del>  A wildcard "*" (wildcard) in the expression "[*]" selects all children of an object or an array and in the expression "..[*]" Filter expressions "?<boolean expr>" select certain children of an object or array as in <del> 1.3.4. </del>  tbl-overview provides a quick overview of the JSONPath syntax elements. resource depletion and related errors are comparable to 500 type errors.) <del> The JSON value the JSONPath query is applied to is, by definition, a valid JSON value.  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 specification.  Sections RFC8259 and RFC8259 of RFC8259 identify specific situations that may conform to the grammar for JSON texts but are not interoperable uses of JSON, as they may cause unpredictable behavior.  The present specification does not attempt to define predictable behavior for JSONPath queries in these situations. Specifically, the "Semantics" subsections of Sections name-selector, wildcard, filter-selector, and descendant-segment describe behavior that becomes unpredictable when the JSON value for one of the objects under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name (name-selector) and comparing strings (comparisons in Section filter- selector) assume these strings are sequences of Unicode scalar values, becoming unpredictable if they aren't (RFC8259). </del> 3.2. Syntactically, a JSONPath query consists of a root identifier ("$"),

The text will be adjusted in a future PR.
This github bug is slowing me down a bit:
Huh! I'm not seeing that.
I'm only seeing it every second time I try to pull the repo state (issues, PRs) into emacs, which seems to use a graphql API. Annoying. This used to work well...
Thanks!

1.3. <ins> The JSON value the JSONPath query is applied to is, by definition, a valid JSON value.  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 specification.  Sections RFC8259 and RFC8259 of RFC8259 identify specific situations that may conform to the grammar for JSON texts but are not interoperable uses of JSON, as they may cause unpredictable behavior.  The present specification does not attempt to define predictable behavior for JSONPath queries in these situations. Specifically, the "Semantics" subsections of Sections name-selector, wildcard, filter-selector, and descendant-segment describe behavior that becomes unpredictable when the JSON value for one of the objects under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name (name-selector) and comparing strings (comparisons in Section filter- selector) assume these strings are sequences of Unicode scalar values, becoming unpredictable if they aren't (RFC8259). 1.4. </ins> A JSONPath expression is applied to a JSON value, the .  The output is a nodelist. of zero or more segments each of which contains one or more selectors.  <ins> 1.4.1. </ins> The in the context of the evaluation of a filter expression (described later).  <ins> 1.4.2. </ins> Segments can use the various shorthands in terms of bracket notation.  Examples and descriptions use shorthands where convenient.  <ins> 1.4.3. </ins> A wildcard "*" (wildcard) in the expression "[*]" selects all children of an object or an array and in the expression "..[*]" Filter expressions "?<boolean expr>" select certain children of an object or array as in  <ins> 1.4.4. </ins> tbl-overview provides a quick overview of the JSONPath syntax elements. resource depletion and related errors are comparable to 500 type errors.)  3.2. Syntactically, a JSONPath query consists of a root identifier ("$"),


"array" in particular do not take on a generic meaning, such as they would in a general programming context. <del> Additional terms used in this specification are defined below. </del>  1.1.1. <del> This specification models the argument as a tree of JSON values, each with its own node.  A node is either the root node or one of its </del>  descendants. <del> This specification models the result of applying a query to the argument as a nodelist (a list of nodes). </del>  So nodes are the selectable parts of the argument.  The only parts of an object that can be selected by a query are the member values. 's popular JSONPath proposal dated 2007-02-21 JSONPath-orig, builds on the experience from the widespread deployment of its <del> implementations, and provides a normative definition for it. </del>  inspired-by-xpath describes how JSONPath was inspired by XML's XPath XPath. JSONPath was intended as a light-weight companion to JSON <del> implementations on platforms such as PHP and JavaScript, so instead of defining its own expression language like XPath did, JSONPath delegated this to the expression language of the platform.  While the languages in which JSONPath is used do have significant commonalities, over time this caused non-portability of JSONPath expressions between the ensuing platform-specific dialects. The present specification aims to remove platform dependencies and serve as a common JSONPath specification that can be used across platforms.  Obviously, this means that backwards compatibility could not always be achieved; a design principle of this specification is to go with a "consensus" between implementations even if it is rough, as long as that does not jeopardize the objective of obtaining a usable, stable JSON query language. </del>  1.3. 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 <del> specification.  Sections RFC8259 and RFC8259 of RFC8259 identify specific situations that may conform to the grammar for JSON texts but are not interoperable uses of JSON, as they may cause unpredictable behavior.  The present specification does not attempt to define predictable behavior for JSONPath queries in these situations. </del>  Specifically, the "Semantics" subsections of Sections name-selector, wildcard, filter-selector, and descendant-segment describe behavior Obviously, an implementation can still fail when executing a JSONPath query, e.g., because of resource depletion, but this is not modeled <del> in the present specification.  However, the implementation MUST NOT silently malfunction.  Specifically, if a valid JSONPath query is evaluated against a structured value whose size doesn't fit in the range of exact values, interfering with the correct interpretation of the query, the implementation MUST provide an indication of overflow. </del>  (Readers familiar with the HTTP error model may be reminded of 400 type errors when pondering well-formedness and validity, while 2.3. <del> In this specification, the semantics of a JSONPath query define the </del>  required results and do not prescribe the internal workings of an implementation.

Generally, use "this document" rather than "this specification". Then use the term specification judiciously. Prefer the term "language" to "platform".
Yep, environment is a nice synonym of platform. Thank you for addressing my concern!

"array" in particular do not take on a generic meaning, such as they would in a general programming context.  <ins> Additional terms used in this document are defined below. </ins> 1.1.1.  <ins> This document models the argument as a tree of JSON values, each with its own node.  A node is either the root node or one of its </ins> descendants.  <ins> This document models the result of applying a query to the argument as a nodelist (a list of nodes). </ins> So nodes are the selectable parts of the argument.  The only parts of an object that can be selected by a query are the member values. 's popular JSONPath proposal dated 2007-02-21 JSONPath-orig, builds on the experience from the widespread deployment of its  <ins> implementations, and provides a normative specification for it. </ins> inspired-by-xpath describes how JSONPath was inspired by XML's XPath XPath. JSONPath was intended as a light-weight companion to JSON  <ins> implementations in programming languages such as PHP and JavaScript, so instead of defining its own expression language, like XPath did, JSONPath delegated parts of a query to the underlying runtime, e.g., JavaScript's "eval()" function.  As JSONPath was implemented in more environments, JSONPath expressions became decreasingly portable.  For example, regular expression processing was often delegated to a convenient regular expression engine. This document aims to remove such implementation-specific dependencies and serve as a common JSONPath specification that can be used across programming languages and environments.  This means that backwards compatibility is not always achieved; a design principle of this document is to go with a "consensus" between implementations even if it is rough, as long as that does not jeopardize the objective of obtaining a usable, stable JSON query language. </ins> 1.3. 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  <ins> document.  Sections RFC8259 and RFC8259 of RFC8259 identify specific situations that may conform to the grammar for JSON texts but are not interoperable uses of JSON, as they may cause unpredictable behavior. This document does not attempt to define predictable behavior for JSONPath queries in these situations. </ins> Specifically, the "Semantics" subsections of Sections name-selector, wildcard, filter-selector, and descendant-segment describe behavior Obviously, an implementation can still fail when executing a JSONPath query, e.g., because of resource depletion, but this is not modeled  <ins> in this document.  However, the implementation MUST NOT silently malfunction.  Specifically, if a valid JSONPath query is evaluated against a structured value whose size doesn't fit in the range of exact values, interfering with the correct interpretation of the query, the implementation MUST provide an indication of overflow. </ins> (Readers familiar with the HTTP error model may be reminded of 400 type errors when pondering well-formedness and validity, while 2.3.  <ins> In this document, the semantics of a JSONPath query define the </ins> required results and do not prescribe the internal workings of an implementation.


This section is informative. <del> A JSONPath expression is applied to a JSON value, the .  The output is a nodelist. </del>  A JSONPath expression consists of an identifier followed by a series of zero or more segments each of which contains one or more 1.4.1. <del> The "$" refers to the of the argument, i.e., to the argument as a whole.  Every JSONPath expression begins with the root node identifier. </del>  <del> The "@" refers to the in the context of the evaluation of a filter expression (described later). </del>  1.4.2. value). The query is a root identifier followed by a sequence of zero or more <del> , each of which is applied to the result of the previous root </del>  identifier or segment and provides input to the next segment.  These results and inputs take the form of a nodelist.

This is currently done inconsistently and doesn't add much value. Instead, define terms in the Terminology section. Reviewers please note: is not modified. This avoids a clash with URL which deletes the term.
Let's wait until lands before sorting this PR out. Meanwhile, rebased on main and kept one of the italicisations which was previously removed.
I've reinstated the other italics which NAME favoured.

This section is informative.  <ins> A JSONPath expression is applied to a JSON value, known as the argument.  The output is a nodelist. </ins> A JSONPath expression consists of an identifier followed by a series of zero or more segments each of which contains one or more 1.4.1.  <ins> The root node identifier "$" refers to the root node of the argument, i.e., to the argument as a whole.  Every JSONPath expression begins with the root node identifier. </ins>  <ins> The current node identifier "@" refers to the current node in the context of the evaluation of a filter expression (described later). </ins> 1.4.2. value). The query is a root identifier followed by a sequence of zero or more  <ins> segments, each of which is applied to the result of the previous root </ins> identifier or segment and provides input to the next segment.  These results and inputs take the form of a nodelist.


under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name <del> (name-selector) and comparing strings (comparisons in Section filter- </del>  selector) assume these strings are sequences of Unicode scalar values, becoming unpredictable if they are not (RFC8259). )-1]. <del> The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further errors relating to the well-formedness and the validity of a JSONPath query can be raised during application of the query to a value. </del>  Obviously, an implementation can still fail when executing a JSONPath query, e.g., because of resource depletion, but this is not modeled . <del> The syntax and semantics of segments are defined in Section segments- details. </del>  2.3. expression, usually involving the current node, is evaluated and the current node is selected if and only if the expression yields true. <del> Paths in filter expressions are Singular Paths, each of which selects at most one node. </del> The current node is accessible via the current node identifier "@".  Parentheses MAY be used within "boolean-expr" for grouping. <del> Comparisons are restricted to Singular Path values, each of which selects at most one node, and primitive values (that is, numbers, strings, "true", "false", and "null"). </del>  Alphabetic characters in ABNF are case-insensitive, so "e" can be either "e" or "E". 2.5.5.2.4. Filter selectors may use function extensions, which are covered in <del> Section fnex. </del>  2.5.5.3. add filter expression functionality: "Function Extensions". A function extension defines a registered name (see iana-fnex) that <del> can be applied to a sequence of zero or more arguments, resulting in a result.  A function-expression stands for ("returns") a nodelist or a value.  The arguments are filter expressions that are to be interpreted as nodelists or values.  For each argument and for the result, the function extension defines the "kind" of the item, i.e., whether the item is a value or a nodelist ("nodes"). Syntactically, a function-expression can occur anywhere where a singular-path can occur (exist-expr, comparable).  A function- expression that employs a function extension that returns a nodelist MUST return a singular node to be used in a comparable. </del>  2.6.1.  The "length" function extension provides a way to compute the length of a value and make that available for further processing in the filter expression: For any other argument value, the result is one. <del> 2.6.2. </del>  The "count" function extension provides a way to obtain the number of nodes in a nodelist and make that available for further processing in integer, that gives the number of nodes in the nodelist.  Note that there is no deduplication of the nodelist. [dedup] <del> 2.6.3. </del>  The "match" function extension provides a way to check whether (the entirety of, see search below) a given string matches a given regular contained in the string that is the second argument.  The result is "true" if the string matches the iregexp and "false" otherwise. <del> 2.6.4. </del>  The "search" function extension provides a way to check whether a given string contains a substring that matches a given regular expression, which is in I-D.draft-ietf-jsonpath-iregexp form.  Its first argument is a string that is searched for at least one substring that matches the iregexp contained in the string that is the second argument.  The result is "true" if such a substring exists, "false" otherwise.  2.7. Segments apply one or more selectors to an input value and

This PR also addresses URL
My now implements everything in the spec, including this PR. (It also supports math operations in expressions, which isn't part of the spec (yet).) The function infrastructure was a struggle (mostly because I'm in a strongly typed language, I suspect), but once implemented, creating the functions themselves and registering them so that they can be parsed was easy! With my lib, the user would implement a "function definition" interface which exposes the name, the range of parameters expected (min/max), and the logic for the function itself (which follows a pattern defined in my lib). Once an instance of their definition is registered, it's available to be parsed. The parsing logic handles validating that the function receives the correct number of parameters, too, so if you send seven arguments, it'll fail to parse.
Tangentially related to , would we consider the use of a function as an argument to another function. Currently this is not allowed as a function is not a . An example for this may be: to determine if the maximum between and is less than 10.
Yes, I hope to support using the result of a function as an argument to a(nother) function in URL Note that I don't intend to support passing a function as an argument to a(nother) function or returning a function from a(nother) function, as in the following example, which does both:
FWIW I'd be fine with this being in a follow-up PR to .
It actually looks like this is already supported. can be a can be a takes zero or more s as parameters
Would we consider allowing advanced expressions usages? This would return the objects with s 1 and 4. (Yeah, we don't support currently, but the example illustrates the idea.) This would return the object with 1. There are probably other ways expressions could be used, too.
Note that function extensions, with the improvements anticipated in URL, may be able to address the above use cases:
I think what I've written is probably the more intuitive given the gamut of features in programming languages available today. What you have is definitely more functional (i.e. functional programming style), but I would tend toward using the operators for these examples. This issue isn't about "how could this be done with what we have?" but rather "is this something we want to support?"
Interestingly, I found a test in the comparison project that treats an expression as a : .
Here's . There is no consensus among implementations, although 14 of them behave the way this issue is proposing. (Embarrassingly, my Go implementation gets just the opposite of that result. That looks like a bug IIRC.)
2023-01-10 Interim: Do not do this enhancement.
Currently function extensions that return a nodelist must return a nodelist consisting of a single node. When a function extension is used as a comparable, it should be able to return an empty nodelist. When a function extension is used in an existence test, it should be able to return any number of nodes in its nodelist. (Currently, such an existence test always yields true since the returned nodelist is non-empty.)
Also if a function is used as an input to another function, it should be allowed to return multiple nodes.
Agreed. PR 330 addresses this.
This issue was addressed by PR .
I believe this is ready for merging (to serve as the next baseline). My comments can either be resolved or entered as new issues.

under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name  <ins> (name-selector) and comparing strings (comparisons in filter- </ins> selector) assume these strings are sequences of Unicode scalar values, becoming unpredictable if they are not (RFC8259). )-1].  <ins> Uses of function extensions must be correctly typed, as described in fnex. A JSONPath implementation MUST raise an error for any query which is not well-formed and valid.  The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further errors relating to the well-formedness and the validity of a JSONPath query can be raised during application of the query to a value. </ins> Obviously, an implementation can still fail when executing a JSONPath query, e.g., because of resource depletion, but this is not modeled .  <ins> The syntax and semantics of segments are defined in segments-details. </ins> 2.3. expression, usually involving the current node, is evaluated and the current node is selected if and only if the expression yields true.  The current node is accessible via the current node identifier "@". <ins> An existence expression may test the result of a function expression (see fnex). </ins> Parentheses MAY be used within "boolean-expr" for grouping.  <ins> Comparisons are restricted to primitive values (that is, numbers, strings, "true", "false", and "null").  These can be notated as literal values, or they can be derived from Singular Paths, each of which selects at most one node.  Function expressions (see fnex) used in comparison expressions return a primitive value or at most one node. </ins> Alphabetic characters in ABNF are case-insensitive, so "e" can be either "e" or "E". 2.5.5.2.4. Filter selectors may use function extensions, which are covered in  <ins> fnex. </ins> 2.5.5.3. add filter expression functionality: "Function Extensions". A function extension defines a registered name (see iana-fnex) that  <ins> can be applied to a sequence of zero or more arguments, producing a result. A function argument is a "filter-path" or a "comparable". According to filter-selector, a "function-expression" is valid as a "filter-path" or a "comparable". Any function expressions in a query must be well-formed (by conforming to the above ABNF) and correctly typed, otherwise the JSONPath implementation MUST raise an error (see synsem-overview). To define which function expressions are correctly typed, a type system is first introduced. </ins> 2.6.1. <ins> Each argument and result of a function extension must have a declared type. A type is a set of instances.  A type is a subtype of another type if its set of instances (possibly after coercion) is a subset of the set of instances of the other type. tbl-types defines the available types in terms of abstract instances, where "n" denotes a node, "v" denotes a value, and "nl" denotes a non-empty nodelist.  The table also lists the subtypes of each type. Notes: "OptionalNodeOrValue" is an abstraction of a "comparable" (which may appear on either side of a comparison or as a function argument). "OptionalNode" is an abstraction of a Singular Path. "Value" is an abstraction of a primitive value. "Boolean" is an abstraction of a primitive value that is either "true" or "false". "OptionalValue" is an abstraction of a primitive value that may also be absent. "Absent" is an abstraction of an empty nodelist. "OptionalNodes" is an abstraction of a "filter-path" (which appears in an existence test or as a function argument). The abstract instances above can be obtained from the concrete representations in tbl-typerep. The following subtype relationships depend on coercion: "OptionalNode" is a subtype of "OptionalValue" via coercion since the "OptionalNode" instance "Node(n)" can be coerced to the "OptionalValue" instance "Value(v)", where "v" is the value of the node "n". "OptionalNode" is a subtype of "OptionalNodes" via coercion since the "OptionalNode" instance "Node(n)" can be coerced to the "OptionalNodes" instance "Nodes(l)", where "l" is a nodelist consisting of just the node "n". The type correctness of function expressions can now be defined in terms of this type system. 2.6.2. A function expression is correctly typed if all the following are true: If it occurs as a "filter-path" in an existence test, the function is defined to have result type "OptionalNodes" or one of its subtypes, or to have result type "OptionalBoolean" or one of its subtypes. If it occurs as a "comparable" in a comparison, the function is defined to have result type "OptionalNodeOrValue" or one of its subtypes. For it and any function expression it contains, each argument of the function matches the defined type of the argument according to one of the following rules: The argument is a function expression with defined result type that is the same as, or a subtype of, the defined type of the argument. The argument is a literal primitive value and the defined type of the argument is "Value" or any type of which "Value" is a subtype. The argument is a Singular Path and the defined type of the argument is "OptionalNode" or any type of which "OptionalNode" is a subtype. The argument is a "filter-path" or a Singular Path and the defined type of the argument is "OptionalNodes". 2.6.3. </ins> The "length" function extension provides a way to compute the length of a value and make that available for further processing in the filter expression: For any other argument value, the result is one.  <ins> 2.6.4. </ins> The "count" function extension provides a way to obtain the number of nodes in a nodelist and make that available for further processing in integer, that gives the number of nodes in the nodelist.  Note that there is no deduplication of the nodelist. [dedup]  <ins> 2.6.5. </ins> The "match" function extension provides a way to check whether (the entirety of, see search below) a given string matches a given regular contained in the string that is the second argument.  The result is "true" if the string matches the iregexp and "false" otherwise.  <ins> The result is "Nothing" if the first argument is not a string or the second argument is not a string conforming to I-D.draft-ietf- jsonpath-iregexp. 2.6.6. </ins> The "search" function extension provides a way to check whether a given string contains a substring that matches a given regular expression, which is in I-D.draft-ietf-jsonpath-iregexp form. <ins> The result is "Nothing" if the first argument is not a string or the second argument is not a string conforming to I-D.draft-ietf- jsonpath-iregexp. </ins> Its first argument is a string that is searched for at least one substring that matches the iregexp contained in the string that is the second argument.  The result is "true" if such a substring exists, "false" otherwise. <ins> 2.6.7. </ins> 2.7. Segments apply one or more selectors to an input value and


"Value" is an abstraction of a primitive value.  "OptionalValue" is an abstraction of a primitive value that may also be absent. If it occurs as a "filter-path" in an existence test, the function is defined to have result type "OptionalNodes" or one of its  subtypes. If it occurs as a "comparable" in a comparison, the function is

Now we have switched to using function extensions for regexp filter matches, the current syntax requires the result to be compared against a boolean, as shown in this example from PR 330: This is consistent with the following statement in the "Existence Tests" section of the spec: If we wanted the following syntax to act as a regexp test: we would have to allow a function expression (returning a boolean result) to be treated as a (rather than an or a ). This would require (a) considerable rework of filter selectors and (b) making a special case of functions which return booleans. To be clear: I am not in favour of such a change. The reason for raising this issue was so that it doesn't come as a surprise to the WG. Thanks to NAME who spotted it when reviewing some draft input to PR 330.
This was fixed by the above PR.
Excellent!

"Value" is an abstraction of a primitive value. <ins> "Boolean" is an abstraction of a primitive value that is either "true" or "false". </ins> "OptionalValue" is an abstraction of a primitive value that may also be absent. If it occurs as a "filter-path" in an existence test, the function is defined to have result type "OptionalNodes" or one of its <ins> subtypes, or to have result type "OptionalBoolean" or one of its </ins> subtypes. If it occurs as a "comparable" in a comparison, the function is


This document models the result of applying a query to the argument as a nodelist (a list of nodes). <del> So nodes are the selectable parts of the argument.  The only parts of an object that can be selected by a query are the member values. Member names and members (name/value pairs) cannot be selected.  So </del>  member values have nodes, but members and member names do not. Similarly, member values are children of an object, but members and member names are not. 2.1. <del> A JSONPath expression is a string which, when applied to a JSON value, the </del>  , selects zero or more nodes of the argument and outputs these nodes as a nodelist. In this document, the semantics of a JSONPath query define the required results and do not prescribe the internal workings of an <del> implementation. </del>  The semantics are that a valid query is executed against a value, the A "dot-member-name-shorthand" of the form ".<member-name>" is shorthand for "['<member-name>']", but can only be used with member names that are composed of certain characters.  Thus, for example, <del> "$.foo.bar" is shorthand for "$['foo']['bar']" (and not for </del>  "$['foo.bar']"). 2.7.1.2.

Signed-off-by: Tim Bray Nothing fancy here, just like the title says.
LGTM, thanks.

This document models the result of applying a query to the argument as a nodelist (a list of nodes).  <ins> Nodes are the selectable parts of the argument.  The only parts of an object that can be selected by a query are the member values.  Member names and members (name/value pairs) cannot be selected.  Thus, </ins> member values have nodes, but members and member names do not. Similarly, member values are children of an object, but members and member names are not. 2.1.  <ins> A JSONPath is a string which, when applied to a JSON value, the </ins> , selects zero or more nodes of the argument and outputs these nodes as a nodelist. In this document, the semantics of a JSONPath query define the required results and do not prescribe the internal workings of an  <ins> implementation.  This document may describe semantics in a procedural step-by-step fashion, but such descriptions are normative only in the sense that any implementation MUST produce an identical result, but not in the sense that implementors are required to use the same algorithms. </ins> The semantics are that a valid query is executed against a value, the A "dot-member-name-shorthand" of the form ".<member-name>" is shorthand for "['<member-name>']", but can only be used with member names that are composed of certain characters.  Thus, for example,  <ins> "$.foo.bar" is shorthand for "$['foo']['bar']" (but not for </ins> "$['foo.bar']"). 2.7.1.2.


subsections, JSONPath defines an extension point that can be used to add filter expression functionality: "Function Extensions".  A function extension defines a registered name (see iana-fnex) that can be applied to a sequence of zero or more arguments, producing a result.

Add note that using the extension point mechanism doesn't imply the "function extensions" to be non-mandatory.

subsections, JSONPath defines an extension point that can be used to add filter expression functionality: "Function Extensions". <ins> This section defines the extension point as well as four function extensions that use this extension point.  While these mechanisms are designed to use the extension point, they are an integral part of the JSONPath specification and are mandatory to implement. </ins> A function extension defines a registered name (see iana-fnex) that can be applied to a sequence of zero or more arguments, producing a result.


"true" or "false". "OptionalValue" is an abstraction of a primitive value that may <del> also be absent. "Absent" is an abstraction of an empty nodelist. </del>  "OptionalNodes" is an abstraction of a "filter-path" (which appears in an existence test or as a function argument).

Remove single-valued type "Absent". This is not useful as a function signature type (parameter or result).
I'm looking at 2.6.1 and wondering if it would be meaningful for a function to have a result type of . How could such a function be used in a filter? If it is the case that this doesn't make sense, that should probably be noted in the text.
By "absent" do you mean "no return value," like a function in C? If so, what would be the point? The usefulness of functions is that they perform calculations on inputs and provide a result.
Indeed, the clarification should be that not all types that make up the type hierarchy are useful as return types. (Which does not mean they need to be outlawed -- they are just not useful.)
No. is a type with one instance ().
I can just about conceive of a logging function that doesn't need to return a value returning type . It could be used in a filter expression like this . I'm not suggesting that's a good idea, but it could be done.
That has no impact on the output of the query, though. Why would one include such a thing? Logging is an implementation/application concern. What? I'm asking about the meaning of . How is it used? What's it's purpose? It doesn't appear in the spec anywhere, so why even ask the question?
2023-01-10 Interim: Remove Absent type.

"true" or "false". "OptionalValue" is an abstraction of a primitive value that may  <ins> alternatively be absent ("Nothing"). </ins> "OptionalNodes" is an abstraction of a "filter-path" (which appears in an existence test or as a function argument).


expression, usually involving the current node, is evaluated and the current node is selected if and only if the expression yields true.  The current node is accessible via the current node identifier "@". This identifier addresses the current node of the filter-selector that is directly enclosing the identifier; note that within nested can be applied to a sequence of zero or more arguments, producing a result.  A function argument is a "filter-path" or a "comparable". According to filter-selector, a "function-expression" is valid as a

clarify that filter expressions are side-effect free and therefore, short-circuiting does not make a difference
In C# (and probably other C-style languages), there are two variants for these operators. and are simple boolean logic. They evaluate all of their operands always (left to right). and are "short-circuit" logic. Their operands are evaluated left to right, and as soon as an outcome is known, it stops evaluating. For example, in , the is never evaluated because returns false so the evaluator knows the entire expression will be false. This becomes important for C# as the operands may be methods which have side effects. If I am trying to parse a , then use the I parsed, I can do that all in one statement: (assume returns a ) In this case, never gets called, which means that no log entry is made. But if I use instead will always be called and a log entry will always be created. ( will be the default (0), but it will still be called.) I'm not sure whether we care about such side effects in JSON Path (I'm leaning towards probably not), but it seems necessary to raise the issue. I expect that if we don't care about side effects, this comes down to an optimization strategy and implementor's choice.
This may become more important if certain function extensions end up having side effects. Perhaps we should say implementations MAY short circuit evaluation. Then it's up to users and function extensions to cope.
Actually, it would already become important as soon as we have exception-like semantics on subexpressions. I'd prefer not to have them.
2023-01-10 Interim: Add text that explicitly excludes side effects that affect the evaluation of JSONpath (e.g., beyond memoization or logging), but makes clear that short-circuiting is a valid implementation strategy; functions need to be pure functions.

expression, usually involving the current node, is evaluated and the current node is selected if and only if the expression yields true. <ins> As the expression is composed of side-effect free components, the order of evaluation does not need to be (and is not) defined. Similarly, for "&&"/"||", both a short-circuiting and a fully evaluating implementation will lead to the same result; both implementation strategies are therefore valid. </ins> The current node is accessible via the current node identifier "@". This identifier addresses the current node of the filter-selector that is directly enclosing the identifier; note that within nested can be applied to a sequence of zero or more arguments, producing a result. <ins> A function extension MUST be defined such that its evaluation is side-effect free, i.e., all possible orders of evaluation and choices of short-circuiting or full evaluation of an expression containing it must lead to the same result.  (Note that memoization or logging are not side effects in this sense as they are visible at the implementation level only -- they do not influence the result of the evaluation.) </ins> A function argument is a "filter-path" or a "comparable". According to filter-selector, a "function-expression" is valid as a


Its only argument is a nodelist.  The result is a value, an unsigned integer, that gives the number of nodes in the nodelist.  Note that <del> there is no deduplication of the nodelist. [dedup] </del>  2.6.5. Other attacks can target the behavior of underlying technologies such as UTF-8 (see RFC3629) and the Unicode character set. <del> Editorial Comments [dedup] Well, that can be discussed. </del>

Delete the editor's note as »Note that there is no deduplication of the nodelist.« is now the agreed behavior.
As currently specified, there is no deduplication of nodes input to the count() function extension. But the spec contains a placeholder suggesting discussion of deduplication. This issue is for that discussion. This issue is related to URL because if function extensions do not have access to node location, then it would not be possible to deduplicate on node identity, only potentially on value.
2023-01-10 Interim: Remove the editor's note now.

Its only argument is a nodelist.  The result is a value, an unsigned integer, that gives the number of nodes in the nodelist.  Note that  <ins> there is no deduplication of the nodelist. </ins> 2.6.5. Other attacks can target the behavior of underlying technologies such as UTF-8 (see RFC3629) and the Unicode character set.


JSONPath queries in these situations. Specifically, the "Semantics" subsections of Sections name-selector, <del> wildcard, filter-selector, and descendant-segment describe behavior that becomes unpredictable when the JSON value for one of the objects under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name (name-selector) and comparing strings (comparisons in filter- selector) assume these strings are sequences of Unicode scalar </del>  values, becoming unpredictable if they are not (RFC8259). 1.4. 1.4.3. <del> A wildcard "*" (wildcard) in the expression "[*]" selects all children of a node and in the expression "..[*]" selects all </del>  descendants of a node. An array slice "start:end:step" (slice) selects a series of elements

(Once completed)
Thanks. is not yet closed; completing this is meant to do that. The triple dot bug was already fixed here in . For me it doesn't matter where additional comments are made. I wonder whether we should finish this round (fixing bugs) before doing a grand renaming. I also would like some feedback on the names proposed...
well, finishing this round before going on is fine.
I think if we agree this we should merge it. Next step could be the great renaming, possibly with some further testing of the grammar. In particular, we should throw collections of JSONPath queries we can find at it. If you have pointers, I could prepare that.
NAME Two sources of queries: URL URL
E.g.,
I propose a slightly more compact naming of ABNF of - and -segment, which should be more consistent between them two. is well known from LaTeX and means or there.
above is wrong (and so it is in the current spec). It needs to read ... to not allow triple dot ( :-)
NAME Wouldn't dotdot-wildcard etc. be less cryptic?
Here are some quibbles with the current ABNF (prior to PR being merged) which we can sort out after The Great Renaming:
Yes, yes. See. Fixed in I like the way this looks like now. Maybe I don't understand; can you elaborate? Fixed this (and following) in Removed in To be fixed in overall overhaul, next Yes! To be fixed in overall overhaul, next To be fixed in overall overhaul, next Fixed in Discuss this in its own issue, I'd say. Fixed in It certainly does not -- it is the subset that is actually needed for normalized paths. To stay normalized, we don't allow random other ones.
Of course ... I'm quite dispassionate here.
Please see my proposal in
With merged, we still have the expression cleanup the separate issue (enhancement) whether should be allowed, to mean
My remaining points are covered by PRs , , and .
Shouldn't be named according to all other above ?
Yes, I agree. See URL
NAME Are we ready to close this issue now the PRs have been merged or did you have more expression cleanup in mind?
The only thing that comes to my mind is standardizing on the column where the is -- this is currently rather chaotic. But that can be a new issue.
Indentation of : number of lines such indented
(And it doesn't need to be consistent, just a bit less chaotic.)
Let's make the a new issue. (I haven't got a good feel for the optimal solution.)
Before we close this issue, URL slipped through the net in my earlier PRs.
Then could resolve to either or . We would introduce an ambiguity, we already found with Json Pointer () ...
OK, with the latest blank space realignments that are part of (5e2cc85), I think we are done with this. ... or do we need two selectors here (Ch.2.61) child-longhand = "[" S selector 1(S "," S selector) S "]" given that '1' means 'at least one'.

JSONPath queries in these situations. Specifically, the "Semantics" subsections of Sections name-selector,  <ins> wildcard-selector, filter-selector, and descendant-segment describe behavior that becomes unpredictable when the JSON value for one of the objects under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name (name-selector) and comparing strings (comparisons in filter-selector) assume these strings are sequences of Unicode scalar </ins> values, becoming unpredictable if they are not (RFC8259). 1.4. 1.4.3.  <ins> A wildcard "*" (wildcard-selector) in the expression "[*]" selects all children of a node and in the expression "..[*]" selects all </ins> descendants of a node. An array slice "start:end:step" (slice) selects a series of elements


Shorthand notations are also provided for when there is a single wildcard or name selector. <del> The "dot-wildcard-shorthand" is shorthand for "[*]". </del>  <del> A "dot-member-name-shorthand" of the form ".<member-name>" is shorthand for "['<member-name>']", but can only be used with member names that are composed of certain characters.  Thus, for example, "$.foo.bar" is shorthand for "$['foo']['bar']" (but not for "$['foo.bar']"). </del>  2.7.1.2. Shortand notations are also provided that correspond to the shorthand forms of the child segment. <del> The "descendant-wildcard-shorthand" is shorthand for "..[*]". </del>  <del> A "descendant-member-name-shorthand" of the form "..<member-name>" is shorthand for "..['<member-name>']". </del>  Note that ".." on its own is not a valid segment.

Can you explain how the test scripts work and how to interpret the output, please?
I haven't done the work to make this a real CI script. You clone the JPC to a directory parallel to where you cloned the I-D repo. kdrfc draft-ietf-jsonpath-URL sh URL ruby scripts/test-abnf-URL > scripts/test-abnf-URL 2>&1 ruby scripts/test-abnf-URL > scripts/test-abnf-URL 2>&1 ruby scripts/test-abnf-URL > scripts/test-abnf-URL 2>&1 ruby scripts/test-URL > scripts/test-URL 2>&1 Compare the output with the checked-in output. (The output contains all parse failures, including the intentional ones. The word FAIL tells you about unexpected output.) An output that says "successfully completed" at the end has done exactly that.
~JPC?~ oh... json path comparison
Is this something that should be in the same repo as the spec? Seems like it should be with a test suite. Or do we plan to remove it before publication?
Indeed -- URL mentioned json-path-comparison (which I call JPC) and jsonpath-compliance-test-suite (which I call CTS). Of course I'd love to get more test data...
This repo contains everything that is needed to work on the spec document. Testing the ABNF in the spec document is a typical case for including tests with the code. It's testing the document. The information in there can possibly be used for building test suites, but I'd rather use the original data in JPC and CTS (which already is a test suite). The test data specifically collected (test-URL) could indeed be used for further testing, but it probably makes more sense to include sample documents and sample query results with that (which were not needed to test just the ABNF). We publish the spec (as an RFC). The repo that creates the spec is public, but not "published" in the stricter sense.
Two objectives: (1) aesthetic cleanup, e.g.: URL (2) more tests, e.g., to be built from query corpora we can find
Looks plausible. I haven't reviewed or run the Ruby code.

Shorthand notations are also provided for when there is a single wildcard or name selector.  <ins> ".*", a "child-segment" directly built from a "wildcard-selector", is shorthand for "[*]". </ins>  <ins> ".<member-name>", a "child-segment" built from a "member-name- shorthand", is shorthand for "['<member-name>']".  Note that this can only be used with member names that are composed of certain characters, as specified in the ABNF rule "member-name-shorthand". Thus, for example, "$.foo.bar" is shorthand for "$['foo']['bar']" (but not for "$['foo.bar']"). </ins> 2.7.1.2. Shortand notations are also provided that correspond to the shorthand forms of the child segment.  <ins> "..*", the "descendant-segment" directly built from a "wildcard- selector", is shorthand for "..[*]". </ins>  <ins> "..<member-name>", a "descendant-segment" built from a "member-name- shorthand", is shorthand for "..['<member-name>']".  As with the similar shorthand of a "child-segment", note that this can only be used with member names that are composed of certain characters, as specified in the ABNF rule "member-name-shorthand". </ins> Note that ".." on its own is not a valid segment.


If the argument value is an object, the result is the number of members in the object. <del> For any other argument value, the result is one. </del>  2.6.4.

For , the spec defines Why return 1? That's a possible value for to return for valid inputs. Wouldn't it make sense to return a value that can't be returned by a valid input, like -1? Currently, this returns the both objects in the array, which is counter-intuitive. The length of the property in is nonsensical because it doesn't contain an property.
Well, I picked this hoping people would notice this... We have two different cases that probably also need different answers. The one the text addresses: A non-container, non-string value, e.g., length(3) I think I can argue that 1 is a good value for that. The one the text does not address: An empty nodelist (Nothing). 1 is definitely not a good value for that. Nothing speaks for -1 except FORTRAN-era conventions. I think we want to be able to return Nothing here.
I disagree. I don't think the "length" of is 1. I think it's nonsensical. Numbers, booleans, nulls, and (really all that's left) don't have a "length." (We've also decided that we don't do any kind of type coersion, so interpreting as is invalid.) I'm happy with this.
I'd be comfortable with returning .
LGTM, thanks.

If the argument value is an object, the result is the number of members in the object.  <ins> For any other argument value, the result is "Nothing". </ins> 2.6.4.