element or member value as the filter selector iterates over the array or object.  A singular path by itself in a Boolean context is an existence test which yields true if the path selects a node and yields false if the <del> path does not select a node.  To be more specific about the actual value of a node selected by a path, explicit comparisons are necessary.  This existence test -- as an exception to the general rule -- also works with nodes with structured values. </del>  When a path resulting in an empty nodelist appears on either side of <del> a comparison, the comparison yields true if and only if the comparison operator is "==", ">=" or "<=" and the other side of the comparison is also a path resulting in an empty nodelist. </del>  <del> When no path resulting in an empty nodelist appears on either side of a comparison, any path which appears on either side of the comparison and results in a nodelist consisting of a single node is replaced by the value of the node and then: </del>  <del> comparison using one of the operators "==" or "!=" yields true if and only if the comparison is between: </del>  <del> primitive values which satisfy the comparison, or </del>  <del> structured values compared using "!=". </del>  <del> comparisons using one of the operators "<", "<=", ">", or ">=" yield true if and only if the comparison is between numeric values which satisfy the comparison. </del>  <del> Note that comparisons between structured values, even if the values are equal, yield false. </del>  <del> Data types are not implicitly converted in comparisons.  So "13 == '13'" yields false. </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 The semantics of regular expressions are as defined in I-D.draft- bormann-jsonpath-iregexp.  The logical AND, OR, and NOT operators have the normal semantics of Boolean algebra and consequently obey these laws (where "P", "Q", and "R" are any expressions with syntax "logical-and-expr", "T" is any

Editorial improvements Correct != comparison involving at least one empty nodelist.
I'm not sure that is so obviously false, so maybe mentioning that a structured value on one side spoils the comparison may be needed.
Ok, I can see how someone might read that into the spec. I'll add something.
Please see the comparison examples I just added. These should help to draw out the implications of the semantics.

element or member value as the filter selector iterates over the array or object. <ins> 3.4.8.2.1. </ins> A singular path by itself in a Boolean context is an existence test which yields true if the path selects a node and yields false if the  <ins> path does not select a node.  This existence test -- as an exception to the general rule -- also works with nodes with structured values. To test the value of a node selected by a path, an explicit comparison is necessary.  For example, to test whether the node selected by the path "@.foo" has the value "null", use "@.foo == null" (see null-semantics) rather than the negated existence test "!@.foo" (which yields false if "@.foo" selects a node, regardless of the node's value). 3.4.8.2.2. </ins> When a path resulting in an empty nodelist appears on either side of  <ins> a comparison, the comparison yields true if and only if: the comparison operator is "==", ">=" or "<=" and the other side of the comparison is also a path resulting in an empty nodelist, or </ins>  <ins> the comparison operator is "!=" and the other side of the comparison is not also a path resulting in an empty nodelist. </ins>  <ins> When any path on either side of a comparison results in a nodelist consisting of a single node, each such path is replaced by the value of its node and then: </ins>  <ins> comparison using one of the operators "==" yields true if and only if the comparison is between equal primitive values. </ins>  <ins> comparisons using one of the operators "<=" or ">=" yield true if and only if the comparison is between numeric values which satisfy the comparison. </ins>  <ins> any comparison of two values using one of the operators "!=", ">", "<" is defined as the negation of the comparison of the same values using the operator "==", "<=", ">=", respectively. </ins>  <ins> Note that "==" comparisons between a structured value and any value, including the same structured value, yield false.  Consequently, "!=" comparisons between a structured value and any value, including the same structured value, yield true. </ins>  <ins> 3.4.8.2.2.1. JSON: 3.4.8.2.3. </ins> 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 The semantics of regular expressions are as defined in I-D.draft- bormann-jsonpath-iregexp. <ins> 3.4.8.2.4. </ins> The logical AND, OR, and NOT operators have the normal semantics of Boolean algebra and consequently obey these laws (where "P", "Q", and "R" are any expressions with syntax "logical-and-expr", "T" is any


Abstract JSONPath defines a string syntax for selecting and extracting values <del> within a JavaScript Object Notation (JSON, RFC 8259) value. </del>  1. <del> JavaScript Object Notation (JSON, RFC8259) is a popular representation format for structured data 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.

because it is no longer needed because the expansion is misleading
Why is the expansion misleading?
I would have thought it was because the notation is not just for objects.
Using the expanded version of the acronym gives the impression that this specification is in some way entangled with JavaScript. (The fact that Glyn reads "JavaScript Object" as a reference to the string-keyed maps JavaScript started out with is another example for the confusion.)
I feel like anyone who knows about JSON had likely come across our asked about its relationship with its namesake. I don't really think this is something that is needed. I mean, do it if it makes you feel better, but it's not really necessary.
In the RFC series, the expansion is no longer needed, which is a good thing, because the expansion is misleading. This PR adapts the JSONPath specification to this fact. I'm not sure what "this" and "it" are in your message. This PR is not about making anyone of us feel better, it is about improving the document to be less misleading.
I think we are all agreed that merging is fine.
LGTM, thanks.

Abstract JSONPath defines a string syntax for selecting and extracting values  <ins> within a JSON (RFC 8259) value. </ins> 1.  <ins> JSON RFC8259 is a popular representation format for structured data values.  JSONPath defines a string syntax for identifying values within 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.


Array slice selector "[<start>:<end>:<step>]", where the optional values "<start>", "<end>", and "<step>" are integer literals <del> Descendants selectors starting with a double dot ".." </del> List selector "[<sel1>,<sel2>,...,<selN>]", holding a comma separated list of index and slice selectors Filter selector "[?(<expr>)]" Current item selector "@" (used in expressions)  Note that processing the dot selector, string-valued index selector, and filter selector all potentially require matching strings against strings, with those strings coming from the JSONPath and from member 3.4.7.1. <del> The descendant selectors start with a double dot ".." and can be followed by an object member name (similar to the "dot-selector"), a wildcard (similar to the "dot-wild-selector"), an "index-selector", "index-wild-selector", "filter-selector", or "list-selector" acting on objects or arrays, or a "slice-selector" acting on arrays. Note that ".." on its own is not a valid selector. 3.4.7.2. A "descendant-selector" selects certain descendants of a node: the "..<name>" form (and the "..[<index>]" form where "<index>" is a "quoted-member-name") selects those descendants that are member values of an object with the given member name. the "..[<index>]" form, where "<index>" is an "element-index", selects those descendants that are array elements with the given index. the "..[<slice-index>]" form selects those descendants that are array elements selected by the given slice. the "..[<filter>]" form selects those descendants that are array elements or object values selected by the given filter. the "..[*]" and "..*" forms select all the descendants. An of the descendants of a node is a sequence of all the descendants in which: nodes of any array appear in array order, nodes appear immediately before all their descendants. This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered. The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node. 3.4.7.3. JSON: Queries: Note: The ordering of the results for the "$..[*]" and "$..*" examples above is not guaranteed, except that: "{"j": 1, "k": 2}" must appear before "1" and "2", "[5, 3, [{"j": 4}]]" must appear before "5", "3", and "[{"j": 4}]", "5" must appear before "3" which must appear before "[{"j": 4}]", "5" and "3" must appear before "{"j": 4}" and "4", "[{"j": 4}]" must appear before "{"j": 4}", and "{"j": 4}" must appear before "4". 3.4.8. 3.4.8.1. </del> The filter selector has the form "[?<expr>]".  It works via iterating over structured values, i.e. arrays and objects. precedence from highest (binds most tightly) to lowest (binds least tightly). <del> 3.4.8.2. </del>  The "filter-selector" works with arrays and objects exclusively.  Its result is a list of element or member value as the filter selector iterates over the array or object. <del> 3.4.8.2.1. </del>  A singular path by itself in a Boolean context is an existence test which yields true if the path selects a node and yields false if the "!@.foo" (which yields false if "@.foo" selects a node, regardless of the node's value). <del> 3.4.8.2.2. </del>  When a path resulting in an empty nodelist appears on either side of a comparison, the comparison yields true if and only if: comparisons between a structured value and any value, including the same structured value, yield true. <del> 3.4.8.2.2.1. </del>  JSON: <del> 3.4.8.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 The semantics of regular expressions are as defined in I-D.draft- bormann-jsonpath-iregexp. <del> 3.4.8.2.4. </del>  The logical AND, OR, and NOT operators have the normal semantics of Boolean algebra and consequently obey these laws (where "P", "Q", and expression that yields true, such as "1 == 1", and "F" is any expression that yields false, such as "1 == 0"): <del> 3.4.8.3. </del>  JSON: Queries: <del> 3.4.9. </del>  The list selector allows combining member names, array indices, slices, and filters in a single selector. operation that involves merging input sets while avoiding duplicates, so the concept was renamed into "list selector". <del> 3.4.9.1. </del>  The list selector is syntactically related to the "dot-selector", "index-selector", "slice-selector", and the "filter-selector".  It contains two or more entries, separated by commas. <del> 3.4.9.2. </del>  A list selector selects the nodes that are selected by at least one of the selector entries in the list and yields the concatenation of components MUST be in the I-JSON range of exact values, see synsem- overview.  3.4.9.3. JSON: Queries:  3.5. Note that JSON "null" is treated the same as any other JSON value: it

I want to take the opportunity of there being no PRs in flight to make this purely editorial change to the order of the spec. It avoids unnecessary forward references to the filter and list selectors.
Another PR opened and merged in less than 8 hours...
Please note this PR was purely editorial. It moved some text around. but didn't change it. (I was planning to merge this later today after a bit more time.)
We should just have a flat policy of 24 hrs for a PR to ensure everyone gets to see it. It doesn't matter if it was a spelling change. Everyone should have a chance to review it.
It's one thing to agree to this policy, which I think we have, and quite another to remember to apply it when one is focussed on other things. I've raised a about automating this check.
Have we? It is not policy I would normally agree to. Editors need to be able to do their work. Github is here to help, not to hinder.
Ah, my mistake: I agreed.
We have a two-week policy for PRs in JSON Schema and it's very helpful to encourage cooperation. I don't think 24 hrs is too much to ask.
Please explain how you did not get a chance to review this change.
The PR opened at 3AM and merged at 10AM. This is an insufficient window. 24 hrs, please. It's not a big request.
You have had time to review after merge. How is a merge such an important event?
If I have objections to a PR, they should be voiced before it's merged. Reviewing after the fact is pointless. Any damage has been done. This particular PR is not one of those cases, but in general, everyone involved should get a chance to review. Why are you so opposed to this? It's one day. That's all I'm asking.
Thanks!

Array slice selector "[<start>:<end>:<step>]", where the optional values "<start>", "<end>", and "<step>" are integer literals  List selector "[<sel1>,<sel2>,...,<selN>]", holding a comma separated list of index and slice selectors Filter selector "[?(<expr>)]" Current item selector "@" (used in expressions) <ins> Descendants selectors starting with a double dot ".." </ins> Note that processing the dot selector, string-valued index selector, and filter selector all potentially require matching strings against strings, with those strings coming from the JSONPath and from member 3.4.7.1.  The filter selector has the form "[?<expr>]".  It works via iterating over structured values, i.e. arrays and objects. precedence from highest (binds most tightly) to lowest (binds least tightly).  <ins> 3.4.7.2. </ins> The "filter-selector" works with arrays and objects exclusively.  Its result is a list of element or member value as the filter selector iterates over the array or object.  <ins> 3.4.7.2.1. </ins> A singular path by itself in a Boolean context is an existence test which yields true if the path selects a node and yields false if the "!@.foo" (which yields false if "@.foo" selects a node, regardless of the node's value).  <ins> 3.4.7.2.2. </ins> When a path resulting in an empty nodelist appears on either side of a comparison, the comparison yields true if and only if: comparisons between a structured value and any value, including the same structured value, yield true.  <ins> 3.4.7.2.2.1. </ins> JSON:  <ins> 3.4.7.2.3. </ins> 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 The semantics of regular expressions are as defined in I-D.draft- bormann-jsonpath-iregexp.  <ins> 3.4.7.2.4. </ins> The logical AND, OR, and NOT operators have the normal semantics of Boolean algebra and consequently obey these laws (where "P", "Q", and expression that yields true, such as "1 == 1", and "F" is any expression that yields false, such as "1 == 0"):  <ins> 3.4.7.3. </ins> JSON: Queries:  <ins> 3.4.8. </ins> The list selector allows combining member names, array indices, slices, and filters in a single selector. operation that involves merging input sets while avoiding duplicates, so the concept was renamed into "list selector".  <ins> 3.4.8.1. </ins> The list selector is syntactically related to the "dot-selector", "index-selector", "slice-selector", and the "filter-selector".  It contains two or more entries, separated by commas.  <ins> 3.4.8.2. </ins> A list selector selects the nodes that are selected by at least one of the selector entries in the list and yields the concatenation of components MUST be in the I-JSON range of exact values, see synsem- overview. <ins> 3.4.8.3. JSON: Queries: 3.4.9. 3.4.9.1. The descendant selectors start with a double dot ".." and can be followed by an object member name (similar to the "dot-selector"), a wildcard (similar to the "dot-wild-selector"), an "index-selector", "index-wild-selector", "filter-selector", or "list-selector" acting on objects or arrays, or a "slice-selector" acting on arrays. Note that ".." on its own is not a valid selector. 3.4.9.2. A "descendant-selector" selects certain descendants of a node: the "..<name>" form (and the "..[<index>]" form where "<index>" is a "quoted-member-name") selects those descendants that are member values of an object with the given member name. the "..[<index>]" form, where "<index>" is an "element-index", selects those descendants that are array elements with the given index. the "..[<slice-index>]" form selects those descendants that are array elements selected by the given slice. the "..[<filter>]" form selects those descendants that are array elements or object values selected by the given filter. the "..[*]" and "..*" forms select all the descendants. An of the descendants of a node is a sequence of all the descendants in which: nodes of any array appear in array order, nodes appear immediately before all their descendants. This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered. The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node. </ins> 3.4.9.3. JSON: Queries: <ins> Note: The ordering of the results for the "$..[*]" and "$..*" examples above is not guaranteed, except that: "{"j": 1, "k": 2}" must appear before "1" and "2", "[5, 3, [{"j": 4}]]" must appear before "5", "3", and "[{"j": 4}]", "5" must appear before "3" which must appear before "[{"j": 4}]", "5" and "3" must appear before "{"j": 4}" and "4", "[{"j": 4}]" must appear before "{"j": 4}", and "{"j": 4}" must appear before "4". </ins> 3.5. Note that JSON "null" is treated the same as any other JSON value: it


3.1. A JSONPath query is a string which selects zero or more nodes of a <del> piece of JSON. </del>  A query MUST be encoded using UTF-8.  The grammar for queries given in this document assumes that its UTF-8 form is first decoded into resource depletion and related errors are comparable to 500 type errors.)  3.2. Syntactically, a JSONPath query consists of a root selector ("$"),

Fixes URL
NAME :
It depends. For example, the APIs of some JSONPath implementations take a rich type which represents a valid JSON value. In that case, handling invalid JSON happens before the API is called and is not a concern of the API. But other implementations could have an API which takes a string, which may or may not represent valid JSON. So, to be clear, we probably need some words in the spec which says the spec does not prescribe how invalid JSON is handled. This is better than silence. Or we could require that invalid JSON cannot result in a non-empty nodelist from a JSONPath query.
NAME But "brokenness" would apply to JSON texts, wouldn't it? As NAME noted in (URL), "JSON text is a sequence of characters, an unparsed piece of JSON for interchange, with newlines and backslashes and all that. JSONPath never looks at JSON texts. JSON value is the RFC 8259 term for what JSONPath looks at." The parser would care about "broken" JSON texts, but JSONPath should never see them.
Agree with last two points. The spec describes the application of a JSONPath expression to parsed JSON, so JSON texts are out-of-scope. As NAME says, we should make that explicit.
JSON Schema simply that it operates on the JSON data model. This section covers a range of issues that we've found in our history, including handling whitespace differences, duplicate keys, etc. I think this is a great approach.
Thanks!

3.1. A JSONPath query is a string which selects zero or more nodes of a  <ins> JSON value. </ins> A query MUST be encoded using UTF-8.  The grammar for queries given in this document assumes that its UTF-8 form is first decoded into resource depletion and related errors are comparable to 500 type errors.) <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. </ins> 3.2. Syntactically, a JSONPath query consists of a root selector ("$"),


3.4.8.2. <del> A list selector selects the nodes that are selected by at least one of the selector entries in the list and yields the concatenation of the lists (in the order of the selector entries) of nodes selected by the selector entries.  Note that any node selected in more than one of the selector entries is kept as many times in the nodelist. </del>  To be valid, integer values in the "element-index" and "slice-index" components MUST be in the I-JSON RFC7493 range of exact values, see 3.4.9.2. <del> A "descendant-selector" selects certain descendants of a node: </del>  <del> the "..<name>" form (and the "..[<index>]" form where "<index>" is a "quoted-member-name") selects those descendants that are member values of an object with the given member name. </del>  <del> the "..[<index>]" form, where "<index>" is an "element-index", selects those descendants that are array elements with the given index. the "..[<slice-index>]" form selects those descendants that are array elements selected by the given slice. the "..[<filter>]" form selects those descendants that are array elements or object values selected by the given filter. the "..[*]" and "..*" forms select all the descendants. An of the descendants of a node is a sequence of all the descendants in which: </del>  nodes of any array appear in array order, This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered. <del> The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node. </del>  3.4.9.3.

Also tweak the wording of the list semantics section. Fixes URL Reviewers may find the useful.
NAME Just a gentle reminder to re-review as I'd like to get this PR merged. Thanks.
The (as of 2022-08-06) for the descendant selector involving a list: Do not state which descendants are selected. Order selected items contrary to current implementations. Lead to contradictions over the ordering of duplicate nodes. It is currently implicit that the list selector should select descendants based on the . This should be made explicit. An applies the path to the value: The spec states: Because of the ordering of the array, in all array-sequenced preorders of the above value, , , and appear before and which appear before which appears before which appears before . So the order of the result according to the spec is: However, the current consensus according to the comparison project is: where it seems the value is traversed once per item of the list (). Consider the path applied to the value: There is just one array-sequenced preorder of this value: (noting the clarification below). But the current produces duplicates and can reorder the elements of an array, so the resultant nodelist would be: which is not a sub-sequence of . We should make it clear that an array-sequenced preorder is of nodes rather than values. For example, consider the path applied to the value: The array-sequenced preorder of this value is and the values selected by are and , but the nodelist is not_ a valid result even though it is a subsequence of the values in the array-sequenced preorder. The result is which is a subsequence of the nodes in the array-sequenced preorder. (In fact, using an array of values to describe an array-sequenced preorder is misleading because it ignores the nodes' locations within the argument value.)
I propose the following actions: Clarify which nodes are selected. Preserve the current ordering, regardless of the implementation consensus, since it easily implemented via a single traversal of the descendants. Allow the descendant list selector to reorder a subsequence of the nodes in an array-sequenced preorder, although it must honour the order of the elements in the selector's list. Clarify the definition of array-sequenced preorder. Any objections?
I don't think you can tell about the ordering from this result, the query is flagged with footnote 4, see (URL), which indicates that these results are being sorted before comparison. A quick check shows that a number of implementations that fall in the consensus (including Goessner JavaScript) actually return
NAME well spotted (and thanks for raising URL). So that leaves the following proposed actions: Clarify which nodes are selected. Allow the descendant list selector to reorder a subsequence of the nodes in an array-sequenced preorder, although it must honour the order of the elements in the selector's list. Clarify the definition of array-sequenced preorder.
That sounds complicated :-) One thing to keep in mind is that implementations that return do not do anything complicated, nor do they "reorder a subsequence of the nodes in an array-sequenced preorder". Rather, they simply apply the selector to each node in the provided node list, and then (for the recursion operator) apply the same logic recursively on the children of each node. That description alone implies the above result.
I agree it sounds complicated. Perhaps, along the lines you describe, it is best to describe the possible orderings of descendants and then say how particular descendant selectors are apply to those descendants.
It may be helpful to think of the recursion operator as an operation that maps the current result list into a new result list according to the following rules: First, create a new empty result list. Then Iterate over the items of the current result list If the current item is an array or object, add it to the end of the new result list. If the current item is an array, iterate over its elements and apply these rules recursively to each element. If the current item is an object, iterate over its members and apply these rules recursively to each member value . This becomes the new current result list. So if the current result list contains the root value the recursive operation produces Then applying the selector to each element in the new current result list produces
I'd prefer to define the orderings of the descendants in terms of a postcondition rather than an algorithm because that avoids implementation bias - a useful property for a spec. Sometimes the postcondition form really doesn't work and we have to resort to an algorithm, for example in the slice semantics. Let's see how the postcondition works out in a PR...
Oh and I would say that describing the part of the descendant selector as a recursion operator is another example of implementation bias (since implementations need not use recursion). The spec talks about descendant selectors because this term describes what the selectors are rather than how they are implemented.

3.4.8.2.  <ins> A list selector selects the nodes that are selected by the selector entries in the list and yields the concatenation of the lists (in the order of the selector entries) of nodes selected by the selector entries.  Note that any node selected in more than one of the selector entries is kept as many times in the nodelist. </ins> To be valid, integer values in the "element-index" and "slice-index" components MUST be in the I-JSON RFC7493 range of exact values, see 3.4.9.2.  <ins> A descendant selector selects zero or more descendants of a node. </ins>  <ins> A nodelist enumerating the descendants is known as a </ins>  <ins> when: </ins> nodes of any array appear in array order, This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered.  <ins> The resultant nodelist of a descendant selector is the result of applying a selector (or no selector), depending on the variant of the descendant selector, to a descendant nodelist, as shown below: </ins> 3.4.9.3.


of its node and then: a comparison using the operator "==" yields true if and only if <del> the comparison is between values of the same primitive type (numbers, strings, booleans, and "null") which are equal. </del>  a comparison using the operator "!=" yields true if and only if <del> the comparison is not between values of the same primitive type (numbers, strings, booleans, and "null") which are equal. </del>  a comparison using one of the operators "<", "<=", ">", or ">=" yields true if and only if the comparison is between values of the first string compares less than the remainder of the second string. <del> Note that "==" comparisons between a structured value (that is, an object or an array) and any value, including the same structured value, yield false and "!=" comparisons between a structured value and any value, including the same structured value, yield true. </del>  3.4.7.2.2.1.

Fixes URL Reviewers may find useful.
You're right about WG concensus. The purpose of this PR and issue URL is to change the WG consensus. Although the "always false" rule is shorter, it's not necessarily simpler as it is a special case, and a counter-intuitive one at that. I think it makes JSONPath harder to understand, by both implementers and users.
RFC 8259 says the names in an object should be unique (but need not be), and ECMA-404 says they are not required to be unique. Should the definition of object equality be tightened allowing for the possibility of non-unique names? That is, should and be considered a possibility and regarded as non-equal? Or does the draft already preclude non-unique names? (NAME proposed test already works if the values associated with non-unique names are different, perhaps it's irrelevant if there are additional duplicate members in one object that are exactly the same. Or there could be a requirement that the number of members in both objects must be the same.)
This PR already copes with objects with non-unique names and it treats and as equal, which I think is ok since an object represents a function from name to value. Non-unique names with distinct values are more problematic since such an object would not represent a function. We could either stick with the current "tight" proposal or weaken it to say that '==' and '!=' are undefined (in other words can be true or false, depending on the implementation) if two objects are being compared, one or both of which have non-unique names.
I'm going to merge and defer this consideration.
For the record, upon further consideration, I am increasingly uncomfortable with this because implementations are required to use recursion bounded only by the size of the document, and I'm dubious about the actual value in production. Let's get this on the agenda for our interim next week.
I'm happy to discuss this next week, but please note that: implementations are not required to use recursion (e.g. they could use a loop and allocate memory in a data structure), the descendant operators might also use recursion bounded only by the size of the document (or use a loop and allocate memory in a data structure). The amount of memory in a data structure could depend on the nesting depth of the structured types in question, but it would be a small fraction of the memory consumed by the parsed JSON document, so I don't think it counts as a separate attack vector.
Now being back again from a longer absent, I am quite impressed, what you (all) have done so far ... thanks. I cannot find the issue, where I already proposed support of (in)equality of structured values (it might have been in the context of operator, before we skipped it). So from my point of view introducing this feature brings with it a higher level of consistency. In the same way I welcome the decision to support lexical ordering of strings for comparison. For testing equality of arrays and objects element- and memberwise comparison is the way to go. There is no reputable ordering of two different arrays based on comparing their elements, at least not in mathematics, where we use the Euclidean Norm of vectors and matrices for that. By substituting as as it seems to be legitimate to consider them if , even when/if and are not ordered. For comparing objects with non-unique names we might pragmatically reuse the JavaScript way, where the latter member overwrites the former (seen from JSON text).
This PR is merged, so this thread might go unnoticed, but let me respond... I think a straightforward ordering of arrays would be lexicographic with a similar spec to that for string ordering. As for ordering objects, we could say that A <= B if all the names of A are names of B and for each name, the value in A is less than or equal to the value in B. Not sure about duplicate names - I'd probably make that case undefined to give maximum freedom to implementations and keep the interop rules consistent with I-JSON. I tend to agree. I'd prefer to avoid semantics based on the order of the JSON text. I'd prefer to go the I-JSON route and make these comparisons unspecified/undefined (i.e. it's ok for implementations to yield true or false).
I also tend to agree with most of your points. I need to read I-JSON again more carefully.
No. ECMA-404, and, to a lesser extent, RFC 8259 describe the format on the wire (JSON texts), which is where they couldn’t (or didn’t want to) summon the energy to exclude members with identical keys. JSONPath operates on JSON values. The text in Section 4 of RFC 8259 is a reflection of the unsavory political issues that prevented this to be clearly defined, it does mention a “name-value mapping”, which is an indication that a map structure was intended; it also reflects the origins of JSON objects as JavaScript objects. JSON texts that violate the interoperability constraints generally turn into true maps during decoding if not causing an error, just not in a way that is predictable for the originator. There is no way JSONPath could react to the deviations in the JSON text, as it only sees the JSON value after decoding. It is very sad that this aspect needs to be rediscussed every time anything uses JSON. Grüße, Carsten
I agree it's sad. Would it be valid for a JSON implementation to implement an object such that a non-unique name is mapped randomly to one of its values? Unless, we can rule out such an implementation, I think we have to accommodate it in JSONPath. I wonder if it's best to have a general statement that the behaviour of JSONPath for objects with non-unique names is undefined. We'd then have to avoid contradicting that general statement by overspecifying the behaviour of object comparisons etc.
interesting ... and yes, it's sad. A JavaScript implementation of JSONPath won't see non-unique member names after parsing JSON text. I don't know how implementations in other languages behave. But nevertheless we need to treat the JSONPath spec as language/implementation agnostic and cannot reliably predict/assume anything ... see RFC 8259 section 4.
Maybe it's best to use a similar wording as in RFC 8259, such as: "When the names within an object are not unique, the behavior of an implementation comparing these name/value pairs is unpredictable."
Well, the language in 8259 has not attracted any negative comments and people seem to understand what it means, so I suggest re-using it.
I guess I'm concerned that a reasonable implementation may be completely predictable. For example, comparing such objects could always yield false. "the behavior of an implementation comparing these name/value pairs is unpredictable" seems to require all implementations to be unpredictable!
Well, the language in 8259 is about JSON texts. We are talking about JSON values.
I think the intention is to say that the originator cannot predict what the consumer will do, hence "unpredictable". (The C language defines "unpredictable behavior" as "might delete all your files", which is a bit outside what we mean here.)
hmm ... implementations are (should be) predictable, but different implementations treating ill-formed JSON cannot yield predictably identical results. Might be referencing I-JSON here of any help ?
Ok, so the spec writer cannot predict what implementations will do. I think that wording is sloppy. I'd much rather say something like "the behaviour is implementation dependent".
The current spec's approach of equality comparisons of structured values always yielding false (and inequality always yielding true) has some downsides: it is likely to surprise users it would be difficult to change the behaviour in future without damaging interoperation So I propose that we support equality/inequality tests of structured values. Out of scope for this issue: introducing literal structured values - these can be introduced later if necessary, ordered comparisons of structured values - these are less likely to be useful and the current spec's approach of these comparisons always yielding false seems reasonable. This issue follows on from URL Note: the current spec includes the comment:
Why? Arrays need to be order-checked because they are inherently ordered.
Because I am trying to focus on changing the WG consensus on comparisons of structured values. If this is successful, I'd be happy to consider addressing the above feature. But I'd like to rule it out of scope for now so we focus on what I think is a fairly simple improvement.
I agree with your sentiment, but I don't think that equality of arrays can be separated from ordering. JSON explicitly states that arrays are ordered, and we need to respect that. Additionally, starting with accepting then coming back and saying that they're not because of ordering is awkward
NAME I think there may be a misunderstanding. I agree that comparisons of arrays should be ordered in the sense that corresponding elements must be compared for equality. That's hopefully clear in URL which says: With that definition, yields false. My out of scope feature "ordered comparisons of structured values" was meant to cover comparisons between structured values using the operators , , , and (like and ). I think there's a reasonable case to be made for such comparisons of arrays, but I'd like to defer it until we've got consensus on and .
Also out of scope for this issue: making yield true if and only if or yield true for all and of the same type, making yield true if and only if or yield true for all and of the same type.
Also out of scope for this issue: equality comparison of objects with non-unique names (see URL)
Co-chair-hat-on: This does not line up with my perception of where the WG consensus was, which was that all == comparisons between structured values were false. Co-chair-hat-off: If the rest of the WG is OK with this I can live with it, but my preference would be to stay with the simpler rule.

of its node and then: a comparison using the operator "==" yields true if and only if  <ins> the comparison is between: values of the same primitive type (numbers, strings, booleans, and "null") which are equal, equal arrays, that is arrays of the same length where each element of the first array yields true when compared using "==" to the corresponding element of the second array, or equal objects, that is objects where: for each member of the first object with name "n" and value "v", there is a member of the second object with name "n" and value "w" where "v" and "w" yield true when comparsed using "==", and for each member of the second object with name "n" and value "v", there is a member of the first object with name "n" and value "w" where "v" and "w" yield true when comparsed using "==". </ins> a comparison using the operator "!=" yields true if and only if  <ins> the comparison is not between equal values of the same type. </ins> a comparison using one of the operators "<", "<=", ">", or ">=" yields true if and only if the comparison is between values of the first string compares less than the remainder of the second string.  <ins> Note that comparisons using any of the operators "<", "<=", ">", or ">=" yield false if either value being compared is an object, array, boolean, or "null". </ins> 3.4.7.2.2.1.


for each member of the first object with name "n" and value "v", there is a member of the second object with name "n" <del> and value "w" where "v" and "w" yield true when comparsed </del>  using "==", and for each member of the second object with name "n" and value "v", there is a member of the first object with name "n" and <del> value "w" where "v" and "w" yield true when comparsed using </del>  "==". a comparison using the operator "!=" yields true if and only if same type which are both numbers or both strings and which satisfy the comparison: <del> numbers in the I-JSON RFC7493 range of exact values MUST compare using the normal mathematical ordering; one or both numbers outside that range MAY compare using an implementation </del>  specific ordering the empty string compares less than any non-empty string

Fix some nits pointed out by NAME Improve definition of children Unicode Scalar Values are integers Typo fix Ordering of non-integer numbers

for each member of the first object with name "n" and value "v", there is a member of the second object with name "n"  <ins> and value "w" where "v" and "w" yield true when compared </ins> using "==", and for each member of the second object with name "n" and value "v", there is a member of the first object with name "n" and  <ins> value "w" where "v" and "w" yield true when compared using </ins> "==". a comparison using the operator "!=" yields true if and only if same type 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 interoperate as per I-JSON MAY compare using an implementation </ins> specific ordering the empty string compares less than any non-empty string


3.4.7.2.4. The logical AND, OR, and NOT operators have the normal semantics of <del> Boolean algebra and consequently obey these laws (where "P", "Q", and "R" are any expressions with syntax "logical-and-expr", "T" is any expression that yields true, such as "1 == 1", and "F" is any expression that yields false, such as "1 == 0"): </del>  3.4.7.3. with double quotes) in JSON texts. The syntax of Normalized Paths is restricted so that there is one and <del> only one way of representing any given Normalized Path.  Putting this another way, for any two distinct Normalized Paths, a JSON value exists that will yield distinct results when the Normalized Paths are applied to it. </del>  Certain characters are escaped, in one and only one way; all other characters are unescaped.

There were picked up by NAME Improve table 1 Improve comparison examples Link to Boolean laws Make some examples shorter More list selector examples Compress two examples into one Clarify description of Normalized Paths
NAME The section concerning you needs more work, but I'm going to merge this PR with what we have and start a new one to improve that section.
NAME This should do it: URL

3.4.7.2.4. The logical AND, OR, and NOT operators have the normal semantics of  <ins> Boolean algebra and obey its laws (see, for example, BOOLEAN-LAWS). </ins> 3.4.7.3. with double quotes) in JSON texts. The syntax of Normalized Paths is restricted so that there is one and  <ins> only one way of identifying a given node.  Putting this another way, two distinct Normalized Paths are never equivalent to each other: there will always be at least one JSON value that yields distinct results when those paths are applied to it. </ins> Certain characters are escaped, in one and only one way; all other characters are unescaped.


The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further <del> errors 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 what happens if a JSON text does not represent valid JSON are not defined by this specification.  3.2. Syntactically, a JSONPath query consists of a root selector ("$"), 3.4.2.2. The "dot-selector" selects the node of the member value corresponding <del> to the member name from any JSON object in its input nodelist.  It selects no nodes from any other JSON value. </del>  3.4.2.3. A "dot-wild-selector" acts as a wildcard by selecting the nodes of all member values of an object in its input nodelist as well as all <del> element nodes of an array in its input nodelist.  Applying the "dot- wild-selector" to a primitive JSON value (a number, a string, "true", "false", or "null") selects no node. </del>  3.4.3.3. The "index-selector" applied with a "quoted-member-name" to an object selects the node of the corresponding member value from it, if and <del> only if that object has a member with that name.  Nothing is selected </del>  from a value that is not a object. The "index-selector" applied with an "element-index" to an array 3.4.5.2. An "index-wild-selector" selects the nodes of all member values of an <del> object as well as of all elements of an array.  Applying the "index- wild-selector" to a primitive JSON value (that is, a number, a string, "true", "false", or "null") selects no node. </del>  The "index-wild-selector" behaves identically to the "dot-wild- selector". or <del> of their array elements or member values, respectively.  Applied to other value types, it will select nothing. </del>  A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the and "null") which are equal, equal arrays, that is arrays of the same length where each <del> element of the first array yields true when compared using "==" to the corresponding element of the second array, or </del>  <del> equal objects, that is objects where: </del>  <del> for each member of the first object with name "n" and value "v", there is a member of the second object with name "n" and value "w" where "v" and "w" yield true when compared using "==", and </del>  <del> for each member of the second object with name "n" and value "v", there is a member of the first object with name "n" and value "w" where "v" and "w" yield true when compared using "==". </del>  a comparison using the operator "!=" yields true if and only if the comparison is not between equal values of the same type. This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered.  The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node.

According to the current draft certain types, such as Booleans, are unordered: equality () and inequality () of values of these types are specified ordered comparisons (, , , and ) are specified to yield false for values of these types. However, is often understood the way it is read: "less than or equal to". Similarly for . If we could define as " or " and as " or ", then they could be easier to understand. With this change , for example, would yield true (whereas according to the current draft, it yields false). There is often an assumption that orderings are "total" or "linear" (see wikipedia for a ). A total order obeys the following laws: But according to the current draft, for example, and both yield false, contrary to the first of the above laws. This is because the ordering of Boolean values is not_ total. In the discussion at today's interim meeting (2022-08-17), it was suggested that the above laws could cause a problem for this issue. This does not appear to be the case because we are not dealing with total orders.
The above section about = is phrased in terms of total orders; I believe this is a POLS violation as most people will not think in terms of total orders here.
NAME Ok. That section isn't necessary: I was merely trying to capture the concern you expressed in the meeting. Please could you explain your concern with the above proposal (ignoring the "Total orders" section)?
Note to self: to avoid delta clashes, I intend to wait for the following PRs to land or close before submitting a PR for this issue: [x] URL [x] URL
Note to self (and anyone else who finds mathematics helpful)... With the proposed change, for all including when is "absent", an object, an array, a boolean, or . Apart from that is just as in the current draft. Similarly for which can be dealt with similarly. The ordering in the current draft is almost a partial order. That is, the following are true for all , , : except that the reflexive axiom is not true if or are "absent", an object, an array, a boolean, or . When restricted to numbers or restricted to strings is a total order. That is if and are both numbers or both strings, then in addition to the partial order axioms, the following is true: Note: is not a total order when restricted to arrays (if we decide to support for arrays), since, for example: The ordering in the current draft is a strict partial order: The of defines in terms of_ : The result is the same as in the current draft except that for all . So, for example, (where is "absent", since ), , and (where and are objects for which ). So is a partial order (without exception) and is still a total order when restricted to numbers or when restricted to strings.
NB. if URL lands, is false, but with the above proposal it would be true.

The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further  <ins> 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 what happens if a JSON text does not represent valid JSON are not defined by this specification. <ins> When a JSONPath query is applied to a JSON value containing an object with duplicate names, the behaviour is unpredictable.  (Such a value usually originates in JSON text containing an object with duplicate keys, but how such a value could be constructed depends on how the JSON text is parsed and how the parsed value is represented.) </ins> 3.2. Syntactically, a JSONPath query consists of a root selector ("$"), 3.4.2.2. The "dot-selector" selects the node of the member value corresponding  <ins> to the member name from any JSON object in its input nodelist.  The behaviour is unpredictable if the JSON object has duplicate names. It selects no nodes from any other JSON value. </ins> 3.4.2.3. A "dot-wild-selector" acts as a wildcard by selecting the nodes of all member values of an object in its input nodelist as well as all  <ins> element nodes of an array in its input nodelist.  The behaviour is unpredictable for an object with duplicate names. Applying the "dot-wild-selector" to a primitive JSON value (a number, a string, "true", "false", or "null") selects no node. </ins> 3.4.3.3. The "index-selector" applied with a "quoted-member-name" to an object selects the node of the corresponding member value from it, if and  <ins> only if that object has a member with that name.  The behaviour is unpredictable if the object has duplicate names.  Nothing is selected </ins> from a value that is not a object. The "index-selector" applied with an "element-index" to an array 3.4.5.2. An "index-wild-selector" selects the nodes of all member values of an  <ins> object as well as of all elements of an array.  The behaviour is unpredictable for an object with duplicate names. Applying the "index-wild-selector" to a primitive JSON value (that is, a number, a string, "true", "false", or "null") selects no node. </ins> The "index-wild-selector" behaves identically to the "dot-wild- selector". or  <ins> of their array elements or member values, respectively.  The behaviour is unpredictable for objects with duplicate names.  Applied to other value types, it will select nothing. </ins> A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the and "null") which are equal, equal arrays, that is arrays of the same length where each  <ins> element of the first array is equal to the corresponding element of the second array, or </ins>  <ins> equal objects with no duplicate names, that is where: </ins>  <ins> both objects have the same collection of names (with no duplicates), and </ins>  <ins> for each of those names, the values associated with the name by the objects are equal. </ins> a comparison using the operator "!=" yields true if and only if the comparison is not between equal values of the same type. This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered. <ins> The behaviour of a "descendant-selector" is unpredictable if the node or one of its descendants is an object with duplicate names. </ins> The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node.


escaping when Normalized Paths appear as strings (which are delimited with double quotes) in JSON texts. <del> The syntax of Normalized Paths is restricted so that there is one and only one way of identifying a given node.  Putting this another way, two distinct Normalized Paths are never equivalent to each other: there will always be at least one JSON value that yields distinct results when those paths are applied to it. </del> Certain characters are escaped, in one and only one way; all other characters are unescaped.

The one to one correspondence sentence gives us most of the desired properties. The fact that for distinct Normalized Paths there will always be at least one JSON value which can distinguish the paths is interesting but not crucial. If it's confusing to some people, then it's probably a distraction.
yes ... this is a good minimalistic solution ... thanks

escaping when Normalized Paths appear as strings (which are delimited with double quotes) in JSON texts.  Certain characters are escaped, in one and only one way; all other characters are unescaped.


The examples are based on the simple JSON value shown in fig-example- value, representing a bookstore (that also has bicycles). <del> The examples in tbl-example use the expression mechanism to obtain the number of elements in an array, to test for the presence of a member in an object, and to perform numeric comparisons of member values with a constant. </del>  3.

The deleted text referred, erroneously, to an example obtaining the number of elements in an array. It also used the term "expression mechanism" instead of "filter expression". On the whole, it seemed better to slim the text down to the bare minimum.

The examples are based on the simple JSON value shown in fig-example- value, representing a bookstore (that also has bicycles).  <ins> tbl-example shows some JSONPath queries that might be applied to this example and their intended results. </ins> 3.


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 <del> defined by this specification. When a JSONPath query is applied to a JSON value containing an object with duplicate names, the behaviour is unpredictable.  (Such a value usually originates in JSON text containing an object with duplicate keys, but how such a value could be constructed depends on how the JSON text is parsed and how the parsed value is represented.) </del>  3.2. 3.4.2.2. The "dot-selector" selects the node of the member value corresponding <del> to the member name from any JSON object in its input nodelist.  The behaviour is unpredictable if the JSON object has duplicate names. </del>  It selects no nodes from any other JSON value. A "dot-wild-selector" acts as a wildcard by selecting the nodes of all member values of an object in its input nodelist as well as all <del> element nodes of an array in its input nodelist.  The behaviour is unpredictable for an object with duplicate names. </del>  Applying the "dot-wild-selector" to a primitive JSON value (a number, a string, "true", "false", or "null") selects no node. The "index-selector" applied with a "quoted-member-name" to an object selects the node of the corresponding member value from it, if and <del> only if that object has a member with that name.  The behaviour is unpredictable if the object has duplicate names.  Nothing is selected </del>  from a value that is not a object. The "index-selector" applied with an "element-index" to an array 3.4.5.2. An "index-wild-selector" selects the nodes of all member values of an <del> object as well as of all elements of an array.  The behaviour is unpredictable for an object with duplicate names. </del>  Applying the "index-wild-selector" to a primitive JSON value (that is, a number, a string, "true", "false", or "null") selects no node. or <del> of their array elements or member values, respectively.  The behaviour is unpredictable for objects with duplicate names.  Applied to other value types, it will select nothing. </del>  A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered. <del> The behaviour of a "descendant-selector" is unpredictable if the node or one of its descendants is an object with duplicate names. </del> The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node.

Centralize the text that explains how non-interoperable JSON may cause unpredictable behavior. This is a little clumsy as the sections to be referenced are currently unnumbered.
Solves a few "behaviours", too :-)
This centralizing approach is a good thing. I suggest to reuse the phrase "duplicate names" for better recognition of the wording in RFC8259, though is more general, as it addresses more than two.
There may be scope for fine-tuning the section cross-referencing, but this can be deferred to purely editorial activity

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  <ins> 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, for instance as they may cause unpredictable behavior.  The present specification does not attempt to define predictable behavior for JSONPath queries in these situations.  (Note that another warning about interoperability, in RFC8259, at the time of writing is generally considered to be overtaken by events and causes no issues with the present specification.) Specifically, the "Semantics" subsections of Sections dot-selector, wildcard, index-selector, index-wildcard-selector, filter-selector, and descendant-selectors describe behavior that turns 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, matching (selectors) and comparing (comparisons in Section filter-selector) of strings assumes these strings are sequences of Unicode scalar values, turning unpredictable if they aren't (RFC8259). </ins> 3.2. 3.4.2.2. The "dot-selector" selects the node of the member value corresponding  <ins> to the member name from any JSON object in its input nodelist. </ins> It selects no nodes from any other JSON value. A "dot-wild-selector" acts as a wildcard by selecting the nodes of all member values of an object in its input nodelist as well as all  <ins> element nodes of an array in its input nodelist. </ins> Applying the "dot-wild-selector" to a primitive JSON value (a number, a string, "true", "false", or "null") selects no node. The "index-selector" applied with a "quoted-member-name" to an object selects the node of the corresponding member value from it, if and  <ins> only if that object has a member with that name.  Nothing is selected </ins> from a value that is not a object. The "index-selector" applied with an "element-index" to an array 3.4.5.2. An "index-wild-selector" selects the nodes of all member values of an  <ins> object as well as of all elements of an array. </ins> Applying the "index-wild-selector" to a primitive JSON value (that is, a number, a string, "true", "false", or "null") selects no node. or  <ins> of their array elements or member values, respectively.  Applied to other value types, it will select nothing. </ins> A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the This definition does not stipulate the order in which the children of an object appear, since JSON objects are unordered.  The resultant nodelist of a "descendant-selector" applied to a node must be a sub-sequence of an array-sequenced preorder of the descendants of the node.


3.4.7.2.2.  When a path resulting in an empty nodelist appears on either side of <del> a comparison, the comparison yields true if and only if: </del>  <del> the comparison operator is "==", ">=" or "<=" and the other side of the comparison is also a path resulting in an empty nodelist, or </del>  <del> the comparison operator is "!=" and the other side of the comparison is not also a path resulting in an empty nodelist. </del>  When any path on either side of a comparison results in a nodelist consisting of a single node, each such path is replaced by the value for each of those names, the values associated with the name by the objects are equal. <del> a comparison using the operator "!=" yields true if and only if the comparison is not between equal values of the same type. a comparison using one of the operators "<", "<=", ">", or ">=" yields true if and only if the 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 first string compares less than the remainder of the second string. <del> Note that comparisons using any of the operators "<", "<=", ">", or ">=" yield false if either value being compared is an object, array, boolean, or "null". </del>  3.4.7.2.2.1.

Changes: Frame in terms of or Frame in terms of or Frame in terms of not Unify the structure of comparisons of absent values and singular values Fixes URL
... this is a significant improvement in Consistency and Simplicity. Thanks for your work.
The current spec defines string comparison using one of the operators , , , or in terms of when one string is less than another. That's fine for , but: for it effectively assumes is fixed (i.e. that for strings and if or ) for and it leaves quite a lot to the reader's imagination. Once we've settled on , the above should be addressed. ~We should also adopt a similar approach for ordered comparisons () of arrays if is adopted.~ (It wasn't.) (I labelled this issue as because I don't believe it will change the intended semantics in either case.)
I propose to let URL land before addressing this issue.
According to the current draft certain types, such as Booleans, are unordered: equality () and inequality () of values of these types are specified ordered comparisons (, , , and ) are specified to yield false for values of these types. However, is often understood the way it is read: "less than or equal to". Similarly for . If we could define as " or " and as " or ", then they could be easier to understand. With this change , for example, would yield true (whereas according to the current draft, it yields false). There is often an assumption that orderings are "total" or "linear" (see wikipedia for a ). A total order obeys the following laws: But according to the current draft, for example, and both yield false, contrary to the first of the above laws. This is because the ordering of Boolean values is not_ total. In the discussion at today's interim meeting (2022-08-17), it was suggested that the above laws could cause a problem for this issue. This does not appear to be the case because we are not dealing with total orders.
The above section about = is phrased in terms of total orders; I believe this is a POLS violation as most people will not think in terms of total orders here.
NAME Ok. That section isn't necessary: I was merely trying to capture the concern you expressed in the meeting. Please could you explain your concern with the above proposal (ignoring the "Total orders" section)?
Note to self: to avoid delta clashes, I intend to wait for the following PRs to land or close before submitting a PR for this issue: [x] URL [x] URL
Note to self (and anyone else who finds mathematics helpful)... With the proposed change, for all including when is "absent", an object, an array, a boolean, or . Apart from that is just as in the current draft. Similarly for which can be dealt with similarly. The ordering in the current draft is almost a partial order. That is, the following are true for all , , : except that the reflexive axiom is not true if or are "absent", an object, an array, a boolean, or . When restricted to numbers or restricted to strings is a total order. That is if and are both numbers or both strings, then in addition to the partial order axioms, the following is true: Note: is not a total order when restricted to arrays (if we decide to support for arrays), since, for example: The ordering in the current draft is a strict partial order: The of defines in terms of_ : The result is the same as in the current draft except that for all . So, for example, (where is "absent", since ), , and (where and are objects for which ). So is a partial order (without exception) and is still a total order when restricted to numbers or when restricted to strings.
NB. if URL lands, is false, but with the above proposal it would be true.

3.4.7.2.2. <ins> The comparison operators "==", "<", and ">" are defined first and then these are used to define "!=", "<=", and ">=". </ins> When a path resulting in an empty nodelist appears on either side of  <ins> a comparison: </ins>  <ins> a comparison using the operator "==" yields true if and only if the comparison is between two paths each of which result in an empty nodelist. </ins>  <ins> a comparison using either of the operators "<" or ">" yields false. </ins> When any path on either side of a comparison results in a nodelist consisting of a single node, each such path is replaced by the value for each of those names, the values associated with the name by the objects are equal.  <ins> a comparison using either of the operators "<" or ">" yields true if and only if the comparison is between values of the same type 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 first string compares less than the remainder of the second string.  <ins> Note that comparisons using either of the operators "<" or ">" yield false if either value being compared is an object, array, boolean, or "null". "!=", "<=" and ">=" are defined in terms of the other comparison operators.  For any "a" and "b": The comparison "a != b" yields true if and only if "a == b" yields false. The comparison "a <= b" yields true if and only if "a < b" yields true or "a == b" yields true. The comparison "a >= b" yields true if and only if "a > b" yields true or "a == b" yields true. </ins> 3.4.7.2.2.1.


tbl-overview provides a quick overview of the JSONPath syntax elements.  2. This section provides some more examples for JSONPath expressions. , i.e., a sequence of zero or more nodes.  The nodelist resulting from the root identifier contains a single node, the argument.  The nodelist resulting from the last segment is presented as the result of the query; depending on the specific API, As a consequence of this approach, if any of the segments produces an empty nodelist, then the whole query produces an empty nodelist. <del> In what follows, the semantics of each segment are defined for each type of node.  It will turn out that the more segments there are in a query, the greater the depth of the nodes of the resultant nodelist in the input value: </del>  <del> A query with N segments, where N >= 0, produces a nodelist consisting of nodes at depth in the input value of N or greater. A query with N segments, where N >= 0, all of which are child- segment, produces a nodelist consisting of nodes precisely at depth N in the input value. </del>  3.4. 3.5.2.2. A "wildcard" selector selects the nodes of all children of an object <del> or array. </del>  The "wildcard" selector selects nothing from a primitive JSON value (that is, a number, a string, "true", "false", or "null"). The following examples show the "wildcard" selector in use by a child segment.  3.5.3. 3.5.3.1. of their array elements or member values, respectively.  Applied to other value types, it will select nothing.  A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the array or object. Queries:  3.6. Segments apply one or more selectors to an input value and concatenate the results into a single nodelist.  The syntax and semantics of each segment are defined below. 3.6.1. appear in the list.  Note that any node matched by more than one selector is kept as many times in the nodelist.  3.6.2. 3.6.2.1. A descendant segment produces zero or more descendants of the input value. <del> A nodelist enumerating the descendants is known as a </del>  <del> when: </del>  <del> nodes of any array appear in array order, </del>  <del> nodes appear immediately before all their descendants. </del>  This definition does not stipulate the order in which the children of <del> an object appear, since JSON objects are unordered. </del>  <del> The resultant nodelist of a descendant segment of the form "..[<selectors>]" is the result of applying the child segment "[<selectors>]" to a descendant nodelist. </del>  3.6.2.3. "{"j": 4}" must appear before "4".  3.7. Note that JSON "null" is treated the same as any other JSON value: it

This PR is a series of changes which are submitted together since they would tread on each other's toes if submitted separately. Fixes URL Fixes URL
NAME I'm going to merge this so I can progress other changes. I'd still appreciate your review and I will apply any fixes in a subsequent PR.
Currently, the JSONPath spec is insufficiently non-deterministic. According to the current draft, in a descendant nodelist, nodes appear immediately before all their descendants. In the example given in the spec, the selector applied to the JSON value: cannot produce the result shown in the table: since does not appear immediately before and (there is an intervening ). Solution: delete the word "immediately". The iteration order of objects is not guaranteed to be the same from one iteration to the next. (For instance, in Go, a JSON object is usually implemented as a map and, according to the , "The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next".) So a list with more than one entry applied to an object can result in a nodelist in which there are sublists in distinct orders. This is the case if each list entry in turn is used to select a nodelist from the object. For example, the JSONPath applied to the value: could produce the nodelist: The descendant selectors can produce similar effects, both in the ordering of the descendant nodelists and in the list form with examples similar to that above. For example, the JSONPath applied to the value: can produce the nodelist: Repeated applications of a JSONPath to a value can result in nodelists which are ordered differently. For example, the JSONPath applied to the value: could produce the nodelist: on one occasion and the nodelist: on a subsequent occasion. Currently, there is no text to define the order of the nodelist resulting from a dot wildcard, index wildcard, or filter selector. The order should preserve array order, but be non-deterministic for objects.
Clarification: Do you mean that the spec should be more non-deterministic? I expect that you mean you want more determinism.
How would you get 4 results from this? I'd expect the output to be just and (in any order).
I agree with the sentiment here. The unorderedness of objects in general is likely going to be an issue for testing.
No. I want less determinism to allow sufficient freedom for implementations.
Oops. Of course. Fixed above.
Should we avoid specifying the order of results at all then? Or, more directly, explicitly state the the order of elements in a nodelist may be determined by the implementation and, because of non-determinism among various JSON implementations, is not subject to consistency?
No, that would be going much too far. For example, it's important that arrays still produce array-ordered nodelists. I agree with that statement, but I wouldn't want to litter the spec with that in multiple places. I'd prefer to use similar language to the current draft, e.g.:
As part of addressing this issue, if PR is merged, we should also define the ordering of resultant nodelists from child and descendant *selectors.
I think the spec should be specific and say that when the nodelist is constructed from members of objects, its ordering is undefined, because the fact that the ordering is not defined for objects. Let's take this issue up tomorrow.
At the 2022-9-27 interim, there was general agreement to implement this issue. There is a need for more extensive examples, especially showing multi-layered cases. There is a concern about how to make a test suite tractable given the level of non-determinism which is being allowed by the spec. The plan is to attack this issue after lands.
The current draft applies descendant selectors to the (strict) descendants of the input value. However, as mentioned in URL, it would better reflect current implementations if descendant selectors applied to the input value as well as its descendants. The comparison project has a for this which shows a consensus among existing implementations.
See URL
NAME I think it would still be legitimate to call the descendant selectors by that name since the values they select are all descendants of the input value. (The one exception would be if we were to allow on its own, in which case the input value would be in the resultant nodelist.)
At the 2022-9-27 interim meeting there was a consensus for implementing this issue.
This sounds a lot better. Just a minor grammatical issue.

tbl-overview provides a quick overview of the JSONPath syntax elements. <ins> This document treats the bracket notations as canonical and defines the above shorthands in terms of the canonical bracket notation. </ins> 2. This section provides some more examples for JSONPath expressions. , i.e., a sequence of zero or more nodes. <ins> Segments can be added to a query to drill further into the structure of the input value. </ins> The nodelist resulting from the root identifier contains a single node, the argument.  The nodelist resulting from the last segment is presented as the result of the query; depending on the specific API, As a consequence of this approach, if any of the segments produces an empty nodelist, then the whole query produces an empty nodelist.  <ins> If a query may produce a nodelist with more than one possible ordering, a particular implementation may also produce distinct orderings in distinct runs of the query. </ins>  <ins> In what follows, the semantics of each segment are defined for each type of node. </ins> 3.4. 3.5.2.2. A "wildcard" selector selects the nodes of all children of an object  <ins> or array.  The order in which the children of an object appear in the resultant nodelist is not stipulated, since JSON objects are unordered.  Children of an array appear in array order in the resultant nodelist. </ins> The "wildcard" selector selects nothing from a primitive JSON value (that is, a number, a string, "true", "false", or "null"). The following examples show the "wildcard" selector in use by a child segment. <ins> The example above with the query "$.o[*, *]" shows that the wildcard selector may produce nodelists in distinct orders each time it appears in the child segment. </ins> 3.5.3. 3.5.3.1. of their array elements or member values, respectively.  Applied to other value types, 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. Children of an array appear in array order in the resultant nodelist. </ins> A relative path, beginning with "@", refers to the current array element or member value as the filter selector iterates over the array or object. Queries: <ins> The example above with the query "$.a[?@.b, ?@.b]" shows that the filter selector may produce nodelists in distinct orders each time it appears in the child segment. </ins> 3.6. Segments apply one or more selectors to an input value and concatenate the results into a single nodelist. <ins> It turns out that the more segments there are in a query, the greater the depth in the input value of the nodes of the resultant nodelist: A query with N segments, where N >= 0, produces a nodelist consisting of nodes at depth in the input value of N or greater. A query with N segments, where N >= 0, all of which are child- segment, produces a nodelist consisting of nodes precisely at depth N in the input value. </ins> The syntax and semantics of each segment are defined below. 3.6.1. appear in the list.  Note that any node matched by more than one selector is kept as many times in the nodelist. <ins> So a child segment drills down one more level into the structure of the input value. </ins> 3.6.2. 3.6.2.1. A descendant segment produces zero or more descendants of the input value.  <ins> A descendant selector of the form "..[<selectors>]" visits each node of the input value and its descendants in such an order that: </ins>  <ins> nodes of any array are visited in array order, and </ins>  <ins> nodes are visited before all their descendants. </ins>  <ins> It applies the child segment "[<selectors>]" to each node and concatenates the resultant nodelists together in the order in which the nodes were visited. </ins> This definition does not stipulate the order in which the children of  <ins> an object are visited, since JSON objects are unordered. Where a selector can produce a nodelist in more than one possible order, the selector may produce nodelists in distinct orders each time it appears in the descendant segment. </ins>  <ins> So a descendant segment drills down one or more levels into the structure of the input value. </ins> 3.6.2.3. "{"j": 4}" must appear before "4". <ins> The example above with the query "$.o..[*, *]" shows that a selector may produce nodelists in distinct orders each time it appears in the descendant segment. </ins> 3.7. Note that JSON "null" is treated the same as any other JSON value: it


JSONPath expressions are applied to a JSON value, the <del> .  Within the JSONPath expression, the abstract name "$" is used to refer to the </del>  <del> of the argument, i.e., to the argument as a whole. </del>  <del> JSONPath expressions use the </del>  , for example: , for example: <del> to build paths that are input to a JSONPath implementation.  A single path may use a combination of bracket and dot notations. </del>  Dot notation is a shorthand way of writing certain bracket notations.  A wildcard "*" (wildcard) in the expression "[*]" selects all children of an object or an array and in the expression "..[*]" selects all descendants of an object or an array. Filter expressions "?<boolean expr>" select certain children of an object or array as in  tbl-overview provides a quick overview of the JSONPath syntax elements. <del> This document treats the bracket notations as canonical and defines the above shorthands in terms of the canonical bracket notation. </del> 2. This section provides examples of JSONPath expressions.  The examples

This is a stab at addressing one NAME review comments in PR .
NAME If you don't think this PR is going in the right direction, please close it and we'll circle back to the matter later.
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

JSONPath expressions are applied to a JSON value, the  <ins> . A JSONPath expression consists of an identifier followed by a series of zero or more segments each of which contains one or more selectors. 1.3.1. The "$" refers to the of the argument, i.e., to the argument as a whole.  Every JSONPath expression begins with the root node identifier. The "@" refers to the </ins>  <ins> in the context of the evaluation of a filter expression (described later). </ins>  <ins> 1.3.2. Segments can use the </ins> , for example: , for example:  <ins> A JSONPath expression may use a combination of bracket and dot notations. </ins> Dot notation is a shorthand way of writing certain bracket notations. <ins> This document treats the bracket notations as canonical and defines various shorthands in terms of bracket notation.  Examples and descriptions use shorthands where convenient. 1.3.3. </ins> A wildcard "*" (wildcard) in the expression "[*]" selects all children of an object or an array and in the expression "..[*]" selects all descendants of an object or an array. Filter expressions "?<boolean expr>" select certain children of an object or array as in <ins> 1.3.4. </ins> tbl-overview provides a quick overview of the JSONPath syntax elements.  2. This section provides examples of JSONPath expressions.  The examples


A descendant segment produces zero or more descendants of the input value. <del> A descendant selector of the form "..[<selectors>]" visits each node of the input value and its descendants in such an order that: </del>  nodes of any array are visited in array order, and <del> nodes are visited before all their descendants. </del>  <del> It applies the child segment "[<selectors>]" to each node and concatenates the resultant nodelists together in the order in which the nodes were visited. </del>  <del> This definition does not stipulate the order in which the children of an object are visited, since JSON objects are unordered. </del>  <del> Where a selector can produce a nodelist in more than one possible order, the selector may produce nodelists in distinct orders each time it appears in the descendant segment. </del>  So a descendant segment drills down one or more levels into the structure of the input value. "{"j": 1, "k": 2}" must appear before "1" and "2", <del> "[5, 3, [{"j": 4}]]" must appear before "5", "3", and "[{"j": 4}]", </del>  <del> "5" must appear before "3" which must appear before "[{"j": 4}]", </del>  <del> "5" and "3" must appear before "{"j": 4}" and "4", </del>  <del> "[{"j": 4}]" must appear before "{"j": 4}", and </del>  <del> "{"j": 4}" must appear before "4". </del>  The example above with the query "$.o..[*, *]" shows that a selector may produce nodelists in distinct orders each time it appears in the descendant segment.  3.7. Note that JSON "null" is treated the same as any other JSON value: it

Give an example to emphasise the spec behaviour. At the time of writing, this disagrees with the implementation consensus here: URL Fixes URL
Please see on the issue. I think we need more semantic text to define what we're looking for.
I've reworked the text in c7f54040f56756c2dd10e05cebbaa0d1a8fb31c1 to make the semantics much more obvious.
The current draft does not agree with the when a descendant segment has multiple selectors. The current draft says that a corresponding child segment containing the whole list of selectors should be applied to a descendant nodelist. The implementation consensus is that each selector is be applied to a descendant nodelist and the results concatenated together. Let's take an example involving arrays (to avoid non-determinism confusing matters). The JSONPath applied to the value according to the current draft gives: but according to the implementation consensus gives: One of the more influential implementations (Jayway) agrees with the current draft. I think it is best to go with the current draft behaviour as this can be implemented in a single traversal of the descendants, but wanted to confirm this here.
Another advantage of the current draft behaviour is that it is more deterministic than the implementation consensus. For example, the JSONPath applied to the value according to the current draft gives: or but according to the implementation consensus (with the non-determinism of URL) gives: or or or
I am very much in favor of cleaning this up. (If the odd behaviors are very widespread, we could combine the cleaned-up semantics with an interoperability warning that applications that rely on the exact sequence will be less interoperable than ones that don't. That is, of course, true of most of what the standard is providing...)
I agree that the current draft is better.
Reading the spec again, While it definitely has instruction for order the results of each selector, I don't think it specifies ordering one way or another for the multiple-selector case. Using the previous example there are two options: Each selector is analyzed separately and the results are concatenated. This is equivalent to (forgive the syntax) . This would (in theory) require multiple data traversals: one for matching and one for matching . All selectors are analyzed together for each node. This is more akin to (again, forgive the syntax) . This would (in theory) process both selectors over a single traversal: as each node is visited, both selectors are applied. It sounds like we want the latter, traversal prioritization.
NAME You quoted an old version of the spec. The current spec says: I think this makes the multi-selector ordering clear.
I still think it's vague on the distinction I mentioned (the two options). Between the two options, I think this text leans more towards the selector prioritization, suggesting that the selector results in their entirety are concatenated.
See URL

A descendant segment produces zero or more descendants of the input value.  <ins> A descendant selector visits the input value and each of its descendants such that: </ins> nodes of any array are visited in array order, and  <ins> nodes are visited before their descendants. </ins>  <ins> The order in which the children of an object are visited is not stipulated, since JSON objects are unordered. </ins>  <ins> Suppose the nodes, in the order visited, are "D1", ..., "Dn" (where "n >= 1").  Note that "D1" is the input value. </ins>  <ins> For each "i" such that "1 <= i <= n", the nodelist "Ri" is defined to be a result of applying the child segment "[<selectors>]" to the node "Di". The result of the descendant selector is the concatenation of "R1", ..., "Rn" (in that order). </ins> So a descendant segment drills down one or more levels into the structure of the input value. "{"j": 1, "k": 2}" must appear before "1" and "2",  <ins> "[5, 3, [{"j": 4}, {"k": 6}]]" must appear before "5", "3", and "[{"j": 4}, {"k": 6}]", </ins>  <ins> "5" must appear before "3" which must appear before "[{"j": 4}, {"k": 6}]", </ins>  <ins> "5" and "3" must appear before "{"j": 4}", "4", ", {"k": 6}", and "6", </ins>  <ins> "[{"j": 4}, {"k": 6}]" must appear before "{"j": 4}" and "{"k": 6}", </ins>  <ins> "{"j": 4}" must appear before "4", and "{"k": 6}" must appear before "6". </ins> The example above with the query "$.o..[*, *]" shows that a selector may produce nodelists in distinct orders each time it appears in the descendant segment. <ins> The example above with the query "$.a..[0, 1]" shows that the child segment "[0, 1]" is applied to each node in turn (rather than the nodes being visited once per selector, which is the case for some JSONPath implementations that do not conform to this specification). </ins> 3.7. Note that JSON "null" is treated the same as any other JSON value: it


Parentheses MAY be used within "boolean-expr" for grouping. <del> Comparisons are restricted to Singular Path values 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". 3.5.5.2.1. <del> A singular path by itself in a Boolean context is an existence test which yields true if the path selects a node and yields false if the path does not select a node.  This existence test -- as an exception to the general rule -- also works with nodes with structured values. </del>  To test the value of a node selected by a path, an explicit comparison is necessary.  For example, to test whether the node

Fixes URL
Usually, existence could be asked in the form "is there any...". We restrict exist-expr to singular paths, though. Do we really want to make this restriction?
I'm trying to think how this would be done practically. All the examples for existence testing are in the form (as you mention). What sorts of plural paths are you suggesting could also test for existence? The only one I can think of would be which I suppose could return any non-empty objects.
-- which top level elements have sub-elements with a fallback member?
It's not obvious to me what you're expecting here. Consider If we try with Jayway JSONPath, an implementation that evaluates as a test for existence, and supports arbitrary JSONPath expressions in filter predicates, we obtain With Jayway semantics, all the evaluations of have to return true for to be accepted.
NAME yes, good question. Note Jayway's logical treatment of existence of all members of an empty set. Evaluating against yields:
Obviously, if the path is no longer singular, there needs to be a definition if this is a ∀ for-all (as in Jayway) or an ∃ exists (as I would have expected from the name).
I see no problem with this. I would also expect this to be an "any exists" operation. Framed more verbosely, the query says "find all children of the root array for which returns a non-empty set." This interpretation would return the first two sub-arrays.
Just to follow up with a comparison with JSONPath, which is another of the dozen implementations in the JSONPath Comparisons that evaluate as a test for existence. Of these dozen implementations, Jayway and Newtonsoft are clearly the most important. Java Jayway is likely the most widely used of all implementations, and is incorporated in Oracle enterprise API's. Newtonsoft JSON.Net shows 2 billion downloads on NuGet. Given and query Newtonsoft JSONPath returns no results. However, given, to my eye, the more natural query Newtonsoft JSONPath returns Jayway, in contrast, when given returns everything,
(Newtonsoft is losing importance as .Net's built-in JSON support continues to grow. Newtonsoft's download count is due to it being available for a couple decades. It's not a good metric to convey current state.)
All the more impressive that Newtonsoft's JSONPath is more expressive than the Committee's attempts :-) At least with supporting a natural query that returns NAME preferred result. Best regards, Daniel
I agree that Newtonsoft's .Net JSONPath isn't as important as Jayway Java JSONPath, which is older. I don't think JSONPath ever achieved the popularity on .Net that Jayway did in Java, where it got incorporated into Oracle enterprise API's. In .Net, users were more likely, once the JSON was mapped into C# types, to use Microsoft technologies, notably LINQ, to query them. On Stack Overflow, it sometimes seems that Jayway JSONPath is JSONPath, to users, who rarely qualify their questions by mentioning the implementation, and to responders, who answer accordingly. For example, a recent questioner asked about the function, which Jayway has, but otherwise is not common. A responder replied referencing a Jayway online site. Neither questioner or responder specifically mentioned "Jayway", but they obviously had a common frame of reference.
Currently, the only relative (NAME path we have is: That would need to be generalized for exist-expr.
NAME I've deleted my comment as it was nonsense! (Probably caused by thoughts of being termed a selector.)
Let's keep this issue open and revisit it as the spec firms up. This was agreed at the 2022-9-27 interim.
I will attempt to add a comparison project test as part of this.
Added: URL There is no calculated consensus among implementations.
Looks like a lot of them do either reject the syntax or otherwise fail to evaluate it, though.
I think that gives us freedom to define this feature the way we want. Compare filter selectors without the outer parentheses (e.g. ) which I'm sure most, if not all, existing implementations would reject with a syntax error.
I'm happy with the textual changes. I'd prefer NAME or someone else look at the ABNF.

Parentheses MAY be used within "boolean-expr" for grouping.  <ins> 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"). </ins> Alphabetic characters in ABNF are case-insensitive, so "e" can be either "e" or "E". 3.5.5.2.1.  <ins> A path by itself in a Boolean context is an existence test which yields true if the path selects at least one node and yields false if the path does not select any nodes. Existence tests differ from comparisons in that: they work with arbitrary relative or absolute paths (not just Singular Paths). they work with paths that select structured values. </ins> To test the value of a node selected by a path, an explicit comparison is necessary.  For example, to test whether the node


3.8.1. <del> "$["u00b1"]" is normalized into (noise in the table and lack of typewriter font is due to RFCXMLv3 limitations). </del> 4. 4.1.

Fixes URL
Do we intend to replace this with anything? What is its purpose in being here?
The N-1 line also illustrates the point so I think it's probably OK to leave it?
Sorry, I didn't pay attention. The purpose of this example was to show that escaped characters are normalized into their actual equivalents (unless there is a reason not to do so). The messiness is a workaround for xml2rfc bugs. I'm confident we can get these bugs fixed before this is published; otherwise we might indeed want to skip this example.
Why doesn't the example already show that an escaped character is normalised into its actual equivalent ("a")?
It does. Many implementers will however think that this only applies to 95-ASCII characters (there is no reason for thinking that, but it is a highly likely misunderstanding).
The last entry in table 15 is completely incomprehensible and the explanation in the following paragraph doesn't help. Not sure how to work around this within the limitations of xml2rfc but maybe just leave it out, it's implicit in the 2nd-last-line example.
NAME I presume you are referring to with the caption "Normalized Path examples". (Table 15 at is a different one.) I agree the example is a mess and doesn't pull its weight, so I'll submit a PR to delete it.
I think it is useful to have an example that shows characters are not normally escaped, even if they are beyond ASCII.
(By the time this goes by the RFC editor, we may be able to get rid of the useless U+.... stuff added by xml2rfc.)