Всегда проверяйте свои необработанные JSON с помощью линтеров (например, https://jsonlint.com/). Этот JSON в вашем вопросе не действителен. Вам нужно это исправить.
Объект "responsibilites"
в вашем JSON содержит только рецепты. Я не уверен, почему вам нужно сравнить его с *_recipe
. Но, учитывая приведенный ниже пример, вы можете легко реализовать это сравнение, если это необходимо. Этот поток может быть полезен в этом отношении.
Вы можете использовать диапазон C ++ 11 для l oop для этих итераций. Просто позаботьтесь о правильном типе, который вы хотите использовать / манипулировать в соответствии с вашим вариантом использования. В случае сомнений обратитесь к быстрому json учебному пособию и документации.
Вот пример с необработанной литеральной строкой в качестве JSON input:
#include <iostream>
#include <rapidjson/document.h>
int main()
{
constexpr auto data = R"json(
{
"responsibilities": {
"starters_recipe": {
"name": "bok choi salad",
"type": "veggie",
"ingredients": {
"leafyIng": "bok choi",
"proteinIng": "tofu",
"seasoning": [{
"2 tsp": "salt",
"1 tsp": "turmric"
}]
}
},
"mainCourse_recipe": {
"name": "pad tai",
"type": "yum yum",
"ingredients": {
"leafyIng": "chard",
"proteinIng": "soylent green",
"seasoning": [{
"2 tsp": "black pepper",
"1 tsp": "tears of the angels"
}]
}
}
}
}
)json";
rapidjson::Document doc;
doc.Parse( data );
const auto& courses = doc["responsibilities"].GetObject();
for ( const auto& course : courses )
{
const auto& course_name = course.name.GetString();
const auto& recipe = courses[course_name].GetObject();
const auto& recipe_name = recipe["name"].GetString();
const auto& ingredients = recipe["ingredients"].GetObject();
const auto& leafyIng = ingredients["leafyIng"].GetString();
const auto& proteinIng = ingredients["proteinIng"].GetString();
const auto& seasoning = ingredients["seasoning"].GetArray()[0].GetObject();
std::cout << "Course: " << course_name << '\n'
<< "Recipe: " << recipe_name << '\n'
<< "Ingredients:\n"
<< "- Leaf : " << leafyIng << '\n'
<< "- Protein : " << proteinIng << '\n'
<< "- Seasoning:\n";
for ( const auto& s : seasoning )
{
const auto& k = s.name.GetString();
const auto& v = s.value.GetString();
std::cout << " - " << k << ", " << v << '\n';
}
std::cout << '\n';
}
return 0;
}
Output :
Course: starters_recipe
Recipe: bok choi salad
Ingredients:
- Leaf : bok choi
- Protein : tofu
- Seasoning:
- 2 tsp, salt
- 1 tsp, turmric
Course: mainCourse_recipe
Recipe: pad tai
Ingredients:
- Leaf : chard
- Protein : soylent green
- Seasoning:
- 2 tsp, black pepper
- 1 tsp, tears of the angels
Массив "seasoning"
содержит только один объект, поэтому эта строка ссылается на 0-й индекс:
const auto& seasoning = ingredients["seasoning"].GetArray()[0].GetObject();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
Я предполагаю, что вы намеревались иметь массив объектов, а не массив с одним объектом.
Это:
"seasoning": [
{ "2 tsp": "black pepper" },
{ "1 tsp": "tears of the angels" }
]
, а не это:
"seasoning": [{
"2 tsp": "black pepper",
"1 tsp": "tears of the angels"
}]
Вы должны манипулировать этим соответствующим образом в коде также.