* Review and extend the documentation, and check it in CI A review of all documentation pages found factual errors, dead links, missing cross-references, and gaps in examples. This fixes them and adds checks so the same problems are caught automatically. Fixes: - wrong signatures and version histories (operator!= C++20 member, binary() subtype type, get<PointerType>(), JSON_NO_THREAD_LOCAL, ...) - stale descriptions (number parsing since #5283, UBJSON table, SAX example that no longer compiled, tsl::ordered_map advice) - dead internal and external links; repology.org badges (the domain is suspended) replaced by badges that query the registries directly - deprecation notes link the migration guide; the guide itself fixed Additions: - "See also" sections, cross-references, 25 runnable examples, 12 Mermaid diagrams, new API pages for json_pointer::operator<=> and byte_container_with_subtype::operator==/!= - landing page, guides for untrusted input and performance - "unreleased" badge after versions newer than the latest release Checks: - strict documentation build (broken links/anchors fail it); CI and the publish workflow fetch the full history the build needs - weekly external link check, Mermaid syntax check in CI - check_structure.py: example titles, heading levels, alt texts, header links, docset index coverage; its unused-example check works again - all examples produce the same output on every platform Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Keep the customer links that could not be fixed A dead link on the customers page is still the evidence of where the use of the library was documented. Keep the original URLs of the entries without a working replacement (Marne, Cisco Webex Desk Camera, Philips Hue, CyberArk) and exclude exactly these URLs from the link check. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Correct the duplicate-key recipe's claim about SAX positions The SAX interface's key() receives no position either; only parse_error() does. Also note that the recipe does not report the path to the repeated key (see discussion #5085). Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Say the library is available as a single header and mention json_fwd.hpp Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Correct documentation errors found while hunting for bugs - patch/patch_inplace: list the JSON pointer errors parse_error.106-109 and out_of_range.402/404, and quote the actual parse_error.105 message. - unflatten: list parse_error.106/107/108 and out_of_range.404. - to_bson: list out_of_range.415 (binary subtype above 255) and note that 412 and 415 are new in 3.13.0. - to_string: state that string_t must be convertible to std::string, also in the StringType requirements table. - JSON Lines: a `while (input >> j)` loop also throws after the last value for concatenated JSON values; show a loop that works for both. - BON8: a string gets 0xFF only if nothing follows it in the message; a string at the end of an array or object is ended by 0xFE. - custom_string_type.hpp: add operator+=(char), which the "Always required" list asks for (json_pointer::to_string, flatten, unflatten, and diff did not compile), and an ADL int_to_string for diff and items. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Cache the release headers with functools.lru_cache Codacy (Pylint) flagged the mutable default argument that header() used as its cache. functools.lru_cache keeps the same memoization without it. The script's output is unchanged. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
90 lines
4.6 KiB
Markdown
90 lines
4.6 KiB
Markdown
# Parsing
|
|
|
|
This library can create a JSON value from a wide range of inputs. This page gives an overview of the available parsing
|
|
functions and how they behave; the linked pages go into more detail.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
I["JSON input"] --> P["parse()"]
|
|
I --> S["sax_parse()"]
|
|
I --> A["accept()"]
|
|
P -->|"optional parser callback filters values"| D["basic_json value (DOM)"]
|
|
S --> H["events delivered to a user SAX handler"]
|
|
A --> V["bool: is the input valid JSON?"]
|
|
```
|
|
|
|
## Input
|
|
|
|
The [`parse`](../../api/basic_json/parse.md) function reads a JSON value from an input. The input can be
|
|
|
|
- a string (`#!cpp std::string`, C string, or string literal),
|
|
- a `#!cpp std::istream` (e.g., an `#!cpp std::ifstream` reading from a file),
|
|
- a `#!cpp FILE*` pointer,
|
|
- a pair of iterators over a contiguous range (e.g., a `#!cpp std::vector<std::uint8_t>`), or
|
|
- a contiguous container.
|
|
|
|
```cpp
|
|
// parse from a string
|
|
json j = json::parse(R"({"happy": true, "pi": 3.141})");
|
|
|
|
// parse from a file
|
|
std::ifstream f("example.json");
|
|
json data = json::parse(f);
|
|
```
|
|
|
|
The input must be encoded in UTF-8; other encodings are not supported. A single input may contain only one JSON value.
|
|
Inputs consisting of multiple values separated by newlines are handled by the [JSON Lines](json_lines.md) format.
|
|
|
|
By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the `parse`
|
|
function — see [comments](../comments.md) and [trailing commas](../trailing_commas.md).
|
|
|
|
## Strictness and trailing data
|
|
|
|
[`parse`](../../api/basic_json/parse.md) reads a single JSON value and requires the whole input to be consumed: any
|
|
non-whitespace data after the value is reported as a parse error. Use it when you want to guarantee that an input is
|
|
exactly one complete JSON document.
|
|
|
|
[`operator>>`](../../api/operator_gtgt.md) follows relaxed `#!cpp std::istream` semantics instead: it parses one JSON
|
|
value and leaves the stream positioned right after it, without requiring the rest of the stream to be consumed. This is
|
|
what makes it possible to read several concatenated values from the same stream, but it also means that "a valid
|
|
document followed by trailing bytes" is accepted rather than rejected. If you are validating conformance, or need to
|
|
reject any input that is not exactly one JSON document, prefer `parse`.
|
|
|
|
When using `operator>>` to read several concatenated values this way, a value that is a number must be followed by
|
|
whitespace, because `operator>>` consumes the character that terminates a number, unless
|
|
[`JSON_PRECISE_STREAM_POSITION`](../../api/macros/json_precise_stream_position.md) is defined to `1` — see the
|
|
[`operator>>` notes](../../api/operator_gtgt.md#notes) for details and examples.
|
|
|
|
## SAX vs. DOM parsing
|
|
|
|
The library offers two parsing models:
|
|
|
|
- **DOM parsing** (the default): the complete input is read and stored as an in-memory `basic_json` value that can be
|
|
traversed and modified freely. This is what [`parse`](../../api/basic_json/parse.md) does, and it is the right choice
|
|
for most use cases.
|
|
- **SAX parsing**: instead of building a value, the parser reports events (such as "a string was read" or "an object
|
|
started") to a handler that you implement. This avoids building the full value in memory and is useful for very large
|
|
inputs or when you only need to extract parts of the input. See the [SAX interface](sax_interface.md) for details and
|
|
[`sax_parse`](../../api/basic_json/sax_parse.md) for the API.
|
|
|
|
You can influence a DOM parse without switching to the SAX interface by passing a
|
|
[parser callback](parser_callbacks.md), which is called during parsing and can, for example, discard parts of the input.
|
|
|
|
## Exceptions
|
|
|
|
When the input is not valid JSON, the `parse` function throws an exception by default. If exceptions are undesired or
|
|
unavailable, the parser can instead return a discarded value, or [`accept`](../../api/basic_json/accept.md) can be used
|
|
to only check whether an input is valid JSON. See [parsing and exceptions](parse_exceptions.md) for the available
|
|
options.
|
|
|
|
## See also
|
|
|
|
- [`parse`](../../api/basic_json/parse.md) - deserialize from a compatible input
|
|
- [`accept`](../../api/basic_json/accept.md) - check if the input is valid JSON
|
|
- [`sax_parse`](../../api/basic_json/sax_parse.md) - generate SAX events
|
|
- [JSON Lines](json_lines.md) - parse newline-delimited JSON
|
|
- [parser callbacks](parser_callbacks.md) - influence the parsing by a callback function
|
|
- [SAX interface](sax_interface.md) - implement a custom SAX handler
|
|
- [parsing and exceptions](parse_exceptions.md) - control error handling
|
|
- [parsing untrusted input](untrusted_input.md) - what to consider when parsing input from untrusted sources
|