From ec352430a03aca084b4cf8d62388206bd9774858 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 17 Oct 2025 13:35:04 -0400 Subject: [PATCH] JSONPath is now an RFC (#2517) * JSONPath is now an RFC * up --- doc/basics.md | 6 +++--- doc/dom.md | 2 +- include/simdjson/dom/array.h | 2 +- include/simdjson/dom/element.h | 2 +- include/simdjson/dom/object-inl.h | 2 +- include/simdjson/dom/object.h | 4 ++-- include/simdjson/generic/ondemand/array.h | 2 +- include/simdjson/generic/ondemand/document.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/basics.md b/doc/basics.md index 3075627a6..56fa04f15 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -452,7 +452,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen * **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`. This will scan through the object looking for the field with the matching string, doing a character-by-character comparison. It may generate the error `simdjson::NO_SUCH_FIELD` if there is no such key in the object, it may throw an exception (see [Error handling](#error-handling)). For efficiency reason, you should avoid looking up the same field repeatedly: e.g., do - not do `object["foo"]` followed by `object["foo"]` with the same `object` instance. Generally, you should not mix and match iterating through an object (`for(auto field : object) {...}`) and key accesses (`object["foo"]`): if you need to iterate through an object after a key access, you need to call `reset()` on the object. Whenever you call `reset()`, you need to keep in mind that though you can iterate over the array repeatedly, values should be consumed only once (e.g., repeatedly calling `unescaped_key()` on the same key is forbidden). Keep in mind that On-Demand does not buffer or save the result of the parsing: if you repeatedly access `object["foo"]`, then it must repeatedly seek the key and parse the content. The library does not provide a distinct function to check if a key is present, instead we recommend you attempt to access the key: e.g., by doing `ondemand::value val{}; if (!object["foo"].get(val)) {...}`, you have that `val` contains the requested value inside the if clause. It is your responsibility as a user to temporarily keep a reference to the value (`auto v = object["foo"]`), or to consume the content and store it in your own data structures. If you consume an + not do `object["foo"]` followed by `object["foo"]` with the same `object` instance. Generally, you should not mix and match iterating through an object (`for(auto field : object) {...}`) and key accesses (`object["foo"]`): if you need to iterate through an object after a key access, you need to call `reset()` on the object. Whenever you call `reset()`, you need to keep in mind that though you can iterate over the array repeatedly, values should be consumedonly once (e.g., repeatedly calling `unescaped_key()` on the same key is forbidden). Keep in mind that On-Demand does not buffer or save the result of the parsing: if you repeatedly access `object["foo"]`, then it must repeatedly seek the key and parse the content. The library does not provide a distinct function to check if a key is present, instead we recommend you attempt to access the key: e.g., by doing `ondemand::value val{}; if (!object["foo"].get(val)) {...}`, you have that `val` contains the requested value inside the if clause. It is your responsibility as a user to temporarily keep a reference to the value (`auto v = object["foo"]`), or to consume the content and store it in your own data structures. If you consume an object twice: `std::string_view(object["foo"]` followed by `std::string_view(object["foo"]` then your code is in error. Furthermore, you can only consume one field at a time, on the same object. The value instance you get from `content["bids"]` becomes invalid when you call `content["asks"]`. @@ -1581,7 +1581,7 @@ JSON Pointer The simdjson library also supports [JSON pointer](https://tools.ietf.org/html/rfc6901) through the `at_pointer()` method, letting you reach further down into the document in a single call. JSON Pointer is supported by both the [DOM approach](https://github.com/simdjson/simdjson/blob/master/doc/dom.md#json-pointer) as well as the On-Demand approach. -**Note:** The On-Demand implementation of JSON Pointer relies on `find_field` which implies that it does not unescape keys when matching. +**Note:** When matching keys, we do a byte-by-byte comparison. We do not unescape keys when matching. Consider the following example: @@ -1696,7 +1696,7 @@ be represented as `value` instances. You can check that a document is a scalar w JSONPath ------------ -The simdjson library supports a subset of [JSONPath](https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index. +The simdjson library supports a subset of [JSONPath](https://www.rfc-editor.org/rfc/rfc9535) (RFC 9535) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index. This implementation relies on `at_path()` converting its argument to JSON Pointer and then calling `at_pointer`, which makes use of [`rewind`](#rewind) to reset the parser at the beginning of the document. Hence, it invalidates all previously parsed values, objects diff --git a/doc/dom.md b/doc/dom.md index f473d90d8..739b3fbb8 100644 --- a/doc/dom.md +++ b/doc/dom.md @@ -313,7 +313,7 @@ JSONPath ------------ -The simdjson library supports a subset of [JSONPath](https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index. +The simdjson library supports a subset of [JSONPath](https://www.rfc-editor.org/rfc/rfc9535) (RFC 9535) through the `at_path()` method, allowing you to reach further into the document in a single call. The subset of JSONPath that is implemented is the subset that is trivially convertible into the JSON Pointer format, using `.` to access a field and `[]` to access a specific index. Consider the following example: diff --git a/include/simdjson/dom/array.h b/include/simdjson/dom/array.h index e964103df..3f0b92b22 100644 --- a/include/simdjson/dom/array.h +++ b/include/simdjson/dom/array.h @@ -111,7 +111,7 @@ public: inline simdjson_result at_pointer(std::string_view json_pointer) const noexcept; /** - * Recursive function which processes the json path of each child element + * Recursive function which processes the JSON path of each child element */ inline void process_json_path_of_child_elements(std::vector::iterator& current, std::vector::iterator& end, const std::string_view& path_suffix, std::vector& accumulator) const noexcept; diff --git a/include/simdjson/dom/element.h b/include/simdjson/dom/element.h index 47f67c275..a661718f4 100644 --- a/include/simdjson/dom/element.h +++ b/include/simdjson/dom/element.h @@ -408,7 +408,7 @@ public: * JSONPath queries that trivially convertible to JSON Pointer queries: key * names and array indices. * - * https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00 + * https://www.rfc-editor.org/rfc/rfc9535 (RFC 9535) * * @return The value associated with the given JSONPath expression, or: * - INVALID_JSON_POINTER if the JSONPath to JSON Pointer conversion fails diff --git a/include/simdjson/dom/object-inl.h b/include/simdjson/dom/object-inl.h index 788ee89dd..ff1d7ceb4 100644 --- a/include/simdjson/dom/object-inl.h +++ b/include/simdjson/dom/object-inl.h @@ -186,7 +186,7 @@ inline simdjson_result> object::at_path_with_wildcard(std:: } if (i >= json_path.size() || (json_path[i] != '.' && json_path[i] != '[')) { - // expect json path to always start with $ but this isn't currently + // expect JSONPath expressions to always start with $ but this isn't currently // expected in jsonpathutil.h. return INVALID_JSON_POINTER; } diff --git a/include/simdjson/dom/object.h b/include/simdjson/dom/object.h index 0b1be2b89..0a3ca0abd 100644 --- a/include/simdjson/dom/object.h +++ b/include/simdjson/dom/object.h @@ -175,7 +175,7 @@ public: inline simdjson_result at_pointer(std::string_view json_pointer) const noexcept; /** - * Recursive function which processes the json path of each child element + * Recursive function which processes the JSON path of each child element */ inline void process_json_path_of_child_elements(std::vector::iterator& current, std::vector::iterator& end, const std::string_view& path_suffix, std::vector& accumulator) const noexcept; @@ -189,7 +189,7 @@ public: * JSONPath queries that trivially convertible to JSON Pointer queries: key * names and array indices. * - * https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00 + * https://www.rfc-editor.org/rfc/rfc9535 (RFC 9535) * * @return The value associated with the given JSONPath expression, or: * - INVALID_JSON_POINTER if the JSONPath to JSON Pointer conversion fails diff --git a/include/simdjson/generic/ondemand/array.h b/include/simdjson/generic/ondemand/array.h index a6450c11e..ab49ddb7d 100644 --- a/include/simdjson/generic/ondemand/array.h +++ b/include/simdjson/generic/ondemand/array.h @@ -107,7 +107,7 @@ public: * JSONPath queries that trivially convertible to JSON Pointer queries: key * names and array indices. * - * https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00 + * https://www.rfc-editor.org/rfc/rfc9535 (RFC 9535) * * @return The value associated with the given JSONPath expression, or: * - INVALID_JSON_POINTER if the JSONPath to JSON Pointer conversion fails diff --git a/include/simdjson/generic/ondemand/document.h b/include/simdjson/generic/ondemand/document.h index 9d1e9f333..12e1965ca 100644 --- a/include/simdjson/generic/ondemand/document.h +++ b/include/simdjson/generic/ondemand/document.h @@ -701,7 +701,7 @@ public: * JSONPath queries that trivially convertible to JSON Pointer queries: key * names and array indices. * - * https://datatracker.ietf.org/doc/html/draft-normington-jsonpath-00 + * https://www.rfc-editor.org/rfc/rfc9535 (RFC 9535) * * Key values are matched exactly, without unescaping or Unicode normalization. * We do a byte-by-byte comparison. E.g.