Search code examples
c++boost

boost: parse json file and get a child


I am trying to pars a JSON file with the following function:

std::string getFieldFromJson_data(std::string json, std::string field)
{
    std::stringstream jsonEncoded(json); // string to stream convertion
    boost::property_tree::ptree root;
    boost::property_tree::read_json(jsonEncoded, root);

    if (root.empty())
        return "";

    return (root.get<std::string>(field));
}

It works when reading elements like

device_json.data_device_id = stoi(getFieldFromJson_data(output, "data.device_id"));

My JSON file looks similar to:

 {
  "data": {
    "device_id": 67,
    "place_open": {
      "monday": [
        "10:15","19:30"
      ]
  }
}
}

I can read the value of "data.device_id", but when i try to read the value of "data.place_open.monday" I get an empty string.


Solution

  • Use a JSON library. Property Tree is not a JSON library. Using Boost JSON and JSON Pointer:

    Live On Coliru

    #include <boost/json.hpp>
    #include <boost/json/src.hpp> // for header-only
    #include <iostream>
    #include <string_view>
    
    auto getField(std::string_view json, std::string_view field) {
      return boost::json::parse(json).at_pointer(field);
    }
    
    int main() {
      auto output = R"({
        "data": {
            "device_id": 67,
            "place_open": {
                "monday": ["10:15", "19:30"]
            }
        }
    })";
    
      for (auto pointer : {
               "/data",
               "/data/device_id",
               "/data/place_open/monday",
               "/data/place_open/monday/0",
               "/data/place_open/monday/1",
           })
        std::cout << pointer << " -> " << getField(output, pointer) << std::endl;
    }
    

    Prints

    /data -> {"device_id":67,"place_open":{"monday":["10:15","19:30"]}}
    /data/device_id -> 67
    /data/place_open/monday -> ["10:15","19:30"]
    /data/place_open/monday/0 -> "10:15"
    /data/place_open/monday/1 -> "19:30"