This commit is contained in:
nlohmann committed 2026-10-12 07:35:31 +00:00
1 parent 79119509a9
commit 22fba27145
555 files changed
+17342 -1394

No files matched your search

+149 -4
View File
@@ -82,13 +82,95 @@ was called:
The example below demonstrates the `parse()` function with and without callback function.
```cpp
--8<-- "examples/parse__string__parser_callback_t.cpp"
#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
// a JSON text
auto text = R"(
{
"Image": {
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor",
"Thumbnail": {
"Url": "http://www.example.com/image/481989943",
"Height": 125,
"Width": 100
},
"Animated" : false,
"IDs": [116, 943, 234, 38793]
}
}
)";
// parse and serialize JSON
json j_complete = json::parse(text);
std::cout << std::setw(4) << j_complete << "\n\n";
// define parser callback
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
{
// skip object elements with key "Thumbnail"
if (event == json::parse_event_t::key and parsed == json("Thumbnail"))
{
return false;
}
else
{
return true;
}
};
// parse (with callback) and serialize JSON
json j_filtered = json::parse(text, cb);
std::cout << std::setw(4) << j_filtered << '\n';
}
```
Output:
```json
--8<-- "examples/parse__string__parser_callback_t.output"
{
"Image": {
"Animated": false,
"Height": 600,
"IDs": [
116,
943,
234,
38793
],
"Thumbnail": {
"Height": 125,
"Url": "http://www.example.com/image/481989943",
"Width": 100
},
"Title": "View from 15th Floor",
"Width": 800
}
}
{
"Image": {
"Animated": false,
"Height": 600,
"IDs": [
116,
943,
234,
38793
],
"Title": "View from 15th Floor",
"Width": 800
}
}
```
## Recipe: rejecting duplicate object keys
@@ -102,13 +184,76 @@ can detect them while the object is still being read, before that ambiguity ever
??? example "Example: reject duplicate object keys"
```cpp
--8<-- "examples/reject_duplicate_keys.cpp"
#include <iostream>
#include <nlohmann/json.hpp>
#include <stdexcept>
#include <string>
#include <unordered_set>
#include <vector>
using json = nlohmann::json;
json parse_strict(const std::string& input)
{
// one key set per nesting depth, reused across sibling objects
std::vector<std::unordered_set<std::string>> keys;
auto reject_duplicate_keys = [&](int depth, json::parse_event_t event, json & parsed)
{
if (event == json::parse_event_t::object_start)
{
// keys of this object are reported at depth+1 (see the event table above)
const auto child_depth = static_cast<std::size_t>(depth) + 1;
if (keys.size() <= child_depth)
{
keys.resize(child_depth + 1);
}
keys[child_depth].clear();
return true;
}
if (event == json::parse_event_t::key)
{
auto& seen = keys[static_cast<std::size_t>(depth)];
const auto& key = parsed.get_ref<const std::string&>();
if (!seen.insert(key).second)
{
throw std::runtime_error("duplicate JSON object key: " + key);
}
return true;
}
return true;
};
return json::parse(input, reject_duplicate_keys);
}
int main()
{
// parsing succeeds when all keys are unique
json j = parse_strict(R"({"one": 1, "two": 2})");
std::cout << j << '\n';
// parsing throws when a key is repeated
try
{
parse_strict(R"({"one": 1, "one": 2})");
}
catch (const std::exception& e)
{
std::cout << e.what() << '\n';
}
}
```
Output:
```json
--8<-- "examples/reject_duplicate_keys.output"
{"one":1,"two":2}
duplicate JSON object key: one
```
This approach has three limitations: