5

I would like to use the Boost (Property Tree) library to parse the following valid JSON file:

{
    "user": {
        "userID": "5C118C8D-AA65-49C0-B907-348DE87D6665",
        "dateProperty": "05-06-2015"
    },
    "challenges": [
        {
            "question#1": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        },
        {
            "question": "answer",
            "value": 5
        }
    ] }

I did validate that the JSON format was correct.

I have also consulted with several site such as:

But I still did not get the proper results. I would like to collect the "user" and "challenges" as key/value pairs. The best result would be to write the "challenges" (question/answers) and user info (userID, dateProperty) into a std::pair that can be written into a std:map.

Any suggestions would be appreciated?

Community
  • 1
  • 1
Ed Johns
  • 211
  • 3
  • 11

1 Answers1

6

UPDATE Since Boost 1.75 prefer Boost JSON, see below.

I think as usual you're just confused about how ptree stores JSON arrays?

Here's a quick demo:

Live On Coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <fstream>

int main()
{
    using namespace boost::property_tree;

    ptree pt;
    read_json(std::cin, pt);

    for (auto& challenge : pt.get_child("challenges"))
        for (auto& prop : challenge.second)
            std::cout << prop.first << ": " << prop.second.get_value<std::string>() << "\n";
}

Prints:

question#1: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5
question: answer
value: 5

UPDATE: Better With Boost JSON

See it Live On Coliru

#include <boost/json.hpp>
#include <boost/json/src.hpp> // for header only
#include <iostream>

int main() {
    std::string const input(std::istreambuf_iterator<char>(std::cin), {});
    boost::json::error_code ec;
    auto doc = boost::json::parse(input, ec);

    for (auto& challenge : doc.at("challenges").as_array()) {
        std::cout << " --- " << challenge << "\n";
        for (auto& [k,v] : challenge.as_object())
            std::cout << k << ": " << v << "\n";
    }
}

Prints

 --- {"question#1":"answer","value":5}
question#1: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
 --- {"question":"answer","value":5}
question: "answer"
value: 5
sehe
  • 374,641
  • 47
  • 450
  • 633