* Document the contract of object keys passed to json_sax::key and key callbacks Describe what the name passed to json_sax::key and to a parser callback for parse_event_t::key holds when parsing JSON text: escapes are decoded to UTF-8, different spellings of a name yield identical strings, the name is validated before the call (invalid escapes or UTF-8 give a parse error and no key event), no normalization or case conversion is applied, the event precedes the ':' check, and duplicate names are reported once per occurrence. Also note that sax_parse passes binary-format keys unchanged. See discussion #5955. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Add a test for the object key contract and correct the BON8 note Pin the guarantees documented for json_sax::key and the key event of parser callbacks: decoded names, validation before delivery, delivery before the colon, one event per repeated name, and the binary formats. BON8 rejects ill-formed UTF-8 in a name even with sax_parse, so the note no longer lists it with the formats that pass bytes through. See discussion #5955. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the GCC build of the object key contract test GCC 11 in C++11 mode rejects a default argument on a lambda parameter (-Wc++14-extensions) and ignores a static_cast<void> on the warn_unused_result of parse(). Pass the input format explicitly and bind the parse result to a variable. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Add version history for the object key contract Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2.6 KiB
2.6 KiB
nlohmann::json_sax::key
virtual bool key(string_t& val) = 0;
An object key was read.
Parameters
val(in)- object key
Return value
Whether parsing should proceed.
Notes
It is safe to move the passed object key value.
When parsing JSON text, val is the decoded object name, not its spelling in the input:
- All escape sequences (
\",\\,\/,\b,\f,\n,\r,\t,\uXXXX, and surrogate pairs) are decoded, and\uXXXXescapes are stored as UTF-8. Different spellings of the same name, such as#!json "/"and#!json "\/", or#!json "\u00e9"and#!json "\u00E9", yield identical strings. An escaped\u0000yields an embedded NUL byte. - The name is scanned and validated completely before
keyis called. If it contains an invalid escape sequence, an unpaired surrogate, a control character, or ill-formed UTF-8, the parse fails with aparse_error, andkeyis not called for it. - No Unicode normalization or case conversion is applied: names that differ in any byte are different strings.
keyis called before the following:is read, so a parse error may still follow for the same member.- A name that occurs several times in the same object is passed once per occurrence.
For the binary formats, object keys contain no escape sequences. For CBOR, MessagePack, UBJSON, and BSON, val holds
the bytes stored in the input, and sax_parse passes them unchanged, without checking them
for valid UTF-8. BON8 encodes characters itself, so an ill-formed name is a parse error and key is not called for it.
Examples
??? example
The example below shows how the SAX interface is used.
```cpp
--8<-- "examples/sax_parse.cpp"
```
Output:
```json
--8<-- "examples/sax_parse.output"
```
See also
start_object- the beginning of an object was readend_object- the end of an object was readsax_parse- SAX parser- SAX Interface - guide to event-based parsing
Version history
- Added in version 3.2.0.
- The behavior described in the notes above (decoded names, validation before
keyis called, no normalization,keybefore the:check, one call per duplicate, bytes of binary formats passed unchanged) is the same in all versions from 3.2.0 on, and for thekeyevent of a parser callback from 3.0.0 on. BSON is only supported from version 3.4.0, and BON8 only from version 3.13.0.