Solveit031
Solveit031

Reputation: 1

How to read JSON file using boost libraries, Boost property tree in C++

i am new to Boost libraries and quite new to programming also. I am trying to read JSON file which is created by hand using boost libraries and boost property tree in C++. I need to use boost property tree to read elements from JSON file

this is my JSON file looks like Example.json

{
    "Shapes":{
        "Square":{
            "dimension1":1234,
            "dimension2":5678
        },
        "Rectangle":{
            "dimension1":4321,
            "dimension2":8765
        },
        "Triangle":{
            "dimension1":2468,
            "dimension2":8642
        }
    }
}

Here i need to read this JSON file using boost property tree using C++ code and boost::property_tree::ptree pt. If I pass Square I am able to read all the dimensions present in that (for eg. "dimension1":1234,"dimension2":5678) and same for Rectangle and Triangle. Please can anyone suggest how to solve this.

I have written below code but it is not working

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

using namespace std;


int main()
{
   
    namespace pt = boost::property_tree;

    
    pt::ptree root;    // Create a root

    
    pt::read_json("Example.json", root);    // Load the json file in this ptree

    std::vector< std::pair<std::string, std::string> > Square;
    
    for (pt::ptree::value_type& result : root.get_child("Square"))
    {
        // Get the label of the node
        std::string label = Square.first;
        std::string content = Square.second.data();
        results.push_back(std::make_pair(label, content));
        cout << Square.second.data();
    }

    return 0;
}

Upvotes: -1

Views: 906

Answers (1)

Micha&#235;l Roy
Micha&#235;l Roy

Reputation: 6496

You're almost there.

Here are a couple of thing your should know about working with propêrty_tree:

  1. By default, property tree report errors by exceptions, so be prepared to catch exception on error, unless you use the *_optional() functions.

  2. If you are looking child "Square" in

    { "Shapes":{ "Square":{ "dimension1":1234, "dimension2":5678 }, "Rectangle":{ "dimension1":4321, "dimension2":8765 }, "Triangle":{ "dimension1":2468, "dimension2":8642 } } },

    its formal name is "Shapes.Sqare". Also, all children of a ptree are ptree themselves (it's a tree).

Your loop becomes:

for (pt::ptree& result : root.get_child("Shapes.Square"))  // get_child could throw!!!
{
    // Get the label of the node
    std::string label = Square.first;
    std::string content = Square.second.data();
    results.push_back(std::make_pair(label, content));
    cout << Square.second.data();
}
  1. Why are you creating a array of string pairs when you already have property_tree handling all of your needs?

You could maybe try something like this:

class Square 
{
      // ...
  private: 
       double width;
       double height;

  public:
    friend boost::property_tree::ptree& operator<< (boost::property_tree::ptree& pt, const Square& square)
    {
        pt.put("dimention1", square.width);
        pt.put("dimention2", square.height);
        return pt;
    }

    friend const boost::property_tree::ptree& operator>> (const boost::property_tree::ptree& pt, Square& square)
    {
        // uses class default values, instead of throwing
        // if a value is missing from json.
        square.width  = pt.get("dimention1", square.width);  
        square.height = pt.get("dimention2", square.height);

        // alternate version that may throw.  Use one or the other
        square.width  = pt.get<double>("dimention1");
        square.height = pt.get<double>("dimention2");

        return pt;
    }
};

// ...

if (auto square_props = root.get_child_optional("Shapes.Square"))
{
    Square sq;
    *square_props >> sq;
    // Do something with sq...
}

Or..

try 
{
    // extract all shapes from json.
    for (const auto& shape : root.get_child("Shapes"))
    {
        if (shape.first == "Square")
        {
            Square sq;
            shape >> sq;  // the same operator>>() works here too.
            // add new square to document...
        }
        // load other shapes  ...
    }
}
catch (boost::property_tree::ptree_bad_path& e)
{
    // no shapes in document, or something is missing...
}

Upvotes: 0

Related Questions