如何在 C++ 中使用嵌套数组解析 JSON 以下并检索结果
How to parse below JSON with nested array in C++ and retrieve the result
我有一个如下所示的 JSON 需要使用 read_json.
在 C++ 中解析
[
{
"key": "123",
"revoked": false,
"metadata": [
{
"visible": true,
"key": "abc",
"value": "0"
},
{
"visible": true,
"key": "cdf",
"value": "0"
}
],
"meterAttributes": []
}
]
在上面的JSON中,元数据及其key/value被检索。
boost::property_tree::read_json(jsonString, pt);
for (auto& outerArray : pt)
{
for (auto& arrayProperty : outerArray.second)
{
if (arrayProperty.first == ws2s(metadata))
{
以上代码没有产生预期的结果。
这是一种方法:
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <sstream>
int main() {
std::istringstream is(
R"aw([{ "key": "123", "revoked": false, "metadata": [ { "visible": true, "key": "abc", "value": "0" }, { "visible": true, "key": "cdf", "value": "0" }], "meterAttributes": [] } ])aw");
boost::property_tree::ptree pt;
boost::property_tree::read_json(is, pt);
//boost::property_tree::write_json(std::cout, pt); // debug
for (auto& outerArray : pt) {
auto mit = outerArray.second.find("metadata"); // use find
for (auto& [mkey, mvalue] : mit->second) {
std::cout << "---\n";
for (auto& [key, value] : mvalue) {
std::cout << key << " = " << value.data() << '\n';
}
}
}
}
输出
---
visible = true
key = abc
value = 0
---
visible = true
key = cdf
value = 0
使用 nlohmann/json.hpp
或任何其他专用 JSON 库的类似代码可能如下所示:
#include <nlohmann/json.hpp>
#include <iostream>
#include <sstream>
int main() {
std::istringstream is(
R"aw([{ "key": "123", "revoked": false, "metadata": [ { "visible": true, "key": "abc", "value": "0" }, { "visible": true, "key": "cdf", "value": "0" }], "meterAttributes": [] } ])aw");
nlohmann::json j;
is >> j;
//std::cout << j[0]["metadata"].dump(2) << "\n\n"; // debug
for(auto& v : j[0]["metadata"]) {
std::cout << "---\n";
std::cout << v["visible"] << '\n';
std::cout << v["key"] << '\n';
std::cout << v["value"] << '\n';
}
}
输出
---
true
"abc"
"0"
---
true
"cdf"
"0"
我建议提升 JSON:
#include <boost/json.hpp>
#include <fmt/ranges.h>
#include <iostream>
namespace json = boost::json;
int main() {
std::map<std::string, std::string> kv;
auto doc = json::parse(sample);
for (auto& toplevel : doc.as_array()) {
for (auto& md : toplevel.at("metadata").as_array()) {
kv.emplace(md.at("key").as_string(), md.at("value").as_string());
}
}
fmt::print("Parsed: {}\n", kv);
}
Parsed: {("abc", "0"), ("cdf", "0")}
备选
如果您坚持使用 Boost PropertyTree(例如,因为您的数据代表一棵 属性 树):Live On Compiler Explorer
#include <boost/property_tree/json_parser.hpp>
#include <fmt/ranges.h>
#include <map>
int main() {
std::map<std::string, std::string> kv;
boost::property_tree::ptree doc;
std::istringstream is(sample);
read_json(is, doc);
for (auto& [_, toplevel] : doc) {
for (auto& [_, md] : toplevel.get_child("metadata")) {
kv.emplace(md.get("key", ""), md.get("value", ""));
}
}
fmt::print("Parsed: {}\n", kv);
}
打印相同。
我有一个如下所示的 JSON 需要使用 read_json.
在 C++ 中解析[
{
"key": "123",
"revoked": false,
"metadata": [
{
"visible": true,
"key": "abc",
"value": "0"
},
{
"visible": true,
"key": "cdf",
"value": "0"
}
],
"meterAttributes": []
}
]
在上面的JSON中,元数据及其key/value被检索。
boost::property_tree::read_json(jsonString, pt);
for (auto& outerArray : pt)
{
for (auto& arrayProperty : outerArray.second)
{
if (arrayProperty.first == ws2s(metadata))
{
以上代码没有产生预期的结果。
这是一种方法:
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <sstream>
int main() {
std::istringstream is(
R"aw([{ "key": "123", "revoked": false, "metadata": [ { "visible": true, "key": "abc", "value": "0" }, { "visible": true, "key": "cdf", "value": "0" }], "meterAttributes": [] } ])aw");
boost::property_tree::ptree pt;
boost::property_tree::read_json(is, pt);
//boost::property_tree::write_json(std::cout, pt); // debug
for (auto& outerArray : pt) {
auto mit = outerArray.second.find("metadata"); // use find
for (auto& [mkey, mvalue] : mit->second) {
std::cout << "---\n";
for (auto& [key, value] : mvalue) {
std::cout << key << " = " << value.data() << '\n';
}
}
}
}
输出
---
visible = true
key = abc
value = 0
---
visible = true
key = cdf
value = 0
使用 nlohmann/json.hpp
或任何其他专用 JSON 库的类似代码可能如下所示:
#include <nlohmann/json.hpp>
#include <iostream>
#include <sstream>
int main() {
std::istringstream is(
R"aw([{ "key": "123", "revoked": false, "metadata": [ { "visible": true, "key": "abc", "value": "0" }, { "visible": true, "key": "cdf", "value": "0" }], "meterAttributes": [] } ])aw");
nlohmann::json j;
is >> j;
//std::cout << j[0]["metadata"].dump(2) << "\n\n"; // debug
for(auto& v : j[0]["metadata"]) {
std::cout << "---\n";
std::cout << v["visible"] << '\n';
std::cout << v["key"] << '\n';
std::cout << v["value"] << '\n';
}
}
输出
---
true
"abc"
"0"
---
true
"cdf"
"0"
我建议提升 JSON:
#include <boost/json.hpp>
#include <fmt/ranges.h>
#include <iostream>
namespace json = boost::json;
int main() {
std::map<std::string, std::string> kv;
auto doc = json::parse(sample);
for (auto& toplevel : doc.as_array()) {
for (auto& md : toplevel.at("metadata").as_array()) {
kv.emplace(md.at("key").as_string(), md.at("value").as_string());
}
}
fmt::print("Parsed: {}\n", kv);
}
Parsed: {("abc", "0"), ("cdf", "0")}
备选
如果您坚持使用 Boost PropertyTree(例如,因为您的数据代表一棵 属性 树):Live On Compiler Explorer
#include <boost/property_tree/json_parser.hpp>
#include <fmt/ranges.h>
#include <map>
int main() {
std::map<std::string, std::string> kv;
boost::property_tree::ptree doc;
std::istringstream is(sample);
read_json(is, doc);
for (auto& [_, toplevel] : doc) {
for (auto& [_, md] : toplevel.get_child("metadata")) {
kv.emplace(md.get("key", ""), md.get("value", ""));
}
}
fmt::print("Parsed: {}\n", kv);
}
打印相同。