简体   繁体   English

如何使用 boost 库读取 JSON 文件,C++ 中的 Boost 属性树

[英]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.我是 Boost 库的新手,也是编程的新手。 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我正在尝试读取 JSON 文件,该文件是在 C++ 中使用 boost 库和 boost 属性树手动创建的。我需要使用 boost 属性树从 JSON 文件中读取元素

this is my JSON file looks like Example.json这是我的 JSON 文件,看起来像 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.在这里,我需要使用 C++ 代码和 boost::property_tree::ptree pt 使用 boost 属性树读取这个 JSON 文件。 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.如果我通过 Square,我能够读取其中存在的所有尺寸(例如“dimension1”:1234,“dimension2”:5678)并且对于 Rectangle 和 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;
}

You're almost there.你快到了。

Here are a couple of thing your should know about working with propêrty_tree:以下是您在使用 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.默认情况下,属性树通过异常报告错误,因此请准备好捕获错误异常,除非您使用 *_optional() 函数。

  2. If you are looking child "Square" in如果您正在寻找儿童“广场”

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

    its formal name is "Shapes.Sqare".它的正式名称是“Shapes.Sqare”。 Also, all children of a ptree are ptree themselves (it's a tree).此外,ptree 的所有孩子本身都是 ptree(它是一棵树)。

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?当您已经有 property_tree 处理您的所有需求时,为什么还要创建一个字符串对数组?

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...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM