首页 > 解决方案 > 使用 boost 读取嵌套的 json 文件

问题描述

我正在尝试读取与 C++ 中的 BOOST 库嵌套的 JSON 格式文件。

我尝试了几件事,浏览了这个论坛中的许多问题,但我找不到任何真正相似的东西,或者那会奏效。

我正在查看的 json 文件具有以下结构

{
    "ABC": {
        "FF:[10.0,20.0]": {
            "GHG:[-2.5,-2.0]": {
                "value": 1.1176470518112183,
                "error": 0.013857235087295462
            },
            "GHG:[1.566,2.0]": {
                "value": 0.9958805441856384,
                "error": 0.027176504445043704
            }
        },
        "FF:[30.0,50.0]": {
            "GHG:[-2.5,-2.0]": {
                "value": 1.1176470518112183,
                "error": 0.013857235087295462
            },
            "GHG:[2.0,2.5]": {
                "value": 1.0464363098144531,
                "error": 0.061588554028766326
            }
        }        
    },
    "ZXY": {
        "FF:[10.0,20.0]": {
            "GHG:[-2.5,-2.0]": {
                "value": 1.1176470518112183,
                "error": 0.013857235087295462
            },
            "GHG:[1.566,2.0]": {
                "value": 0.9958805441856384,
                "error": 0.027176504445043704
            }
        },
        "FF:[30.0,50.0]": {
            "GHG:[-2.5,-2.0]": {
                "value": 1.1176470518112183,
                "error": 0.013857235087295462
            },
            "GHG:[2.0,2.5]": {
                "value": 1.0464363098144531,
                "error": 0.061588554028766326
            }
        }
    }
}

我试图使用此处描述的 BOOST_FOREACH 方法: http ://www.ce.unipr.it/people/medici/boost_ptree.html

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

namespace pt = boost::property_tree;

pt::ptree tree;

int main() {

    pt::read_json("bla.json", tree);

    BOOST_FOREACH(  pt::ptree::value_type const&v, tree.get_child("ABC") ) {
        const std::string & key = v.first;
        const pt::ptree & subtree = v.second; 
        //const pt::ptree & subsubtree = v.second;
        std::cout << key << std::endl;
        if(subtree.empty()) {
            std::cout << "subtree empty" << std::endl;
            } else {
            std::cout << "subtree not empty" << std::endl;

            BOOST_FOREACH(  pt::ptree::value_type const&sv, subtree.get_child(key) ) {
                const std::string & subkey = sv.first; // key
                const pt::ptree & subsubtree = sv.second; // value (or a subnode)
                if(subsubtree.empty()) {
                    std::cout << "subsubtree empty" << std::endl;
                    } else {
                    std::cout << "subsubtree not empty" << std::endl;
                    std::cout << subsubtree.data() << std::endl;
                }
            }
        }
    }
    return 0;
}

但我总是收到一个错误,即没有这样的节点:

terminate called after throwing an instance of 'boost::wrapexcept<boost::property_tree::ptree_bad_path>'
  what():  No such node (FF:[10.0,20.0])
Aborted 

我很确定这不是一个难题,但我是 C++ 的新手,我非常感谢任何帮助!

标签: c++jsonboost

解决方案


最后,我知道你的get_child用法不正确!只需将树传递给基于范围的 for。

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

namespace pt = boost::property_tree;

pt::ptree tree;

int main() {

    pt::read_json("bla.json", tree);

    for(auto&& v : tree.get_child("ABC")) {
        const std::string & key = v.first; // key
        const pt::ptree & subtree = v.second; // value (or a subnode)
        //const pt::ptree & subsubtree = v.second; // value (or a subnode)
        std::cout << key << std::endl;
        if(subtree.empty()) {
            // This is a key:value
            //  use subtree.data() as string value or subtree.get_value<T>()
            std::cout << "subtree empty" << std::endl;
            } else {
            // This is a subtree
            //  use subtree as child
            std::cout << "subtree not empty" << std::endl;

            for(auto&& sv : subtree/*.get_child(pt::path(key, '\0'))*/) {
                [[maybe_unused]]const std::string & subkey = sv.first; // key
                const pt::ptree & subsubtree = sv.second; // value (or a subnode)
                std::cout << subkey << std::endl;
                if(subsubtree.empty()) {
                    std::cout << "subsubtree empty" << std::endl;
                    } else {
                    std::cout << "subsubtree not empty" << std::endl;
                    std::cout << subsubtree.data() << std::endl;
                    for(auto&& ssv: subsubtree) {
                        [[maybe_unused]]const std::string & subsubkey = ssv.first; // key
                        const pt::ptree & subsubsubtree = ssv.second; // value (or a subnode)
                        std::cout << subsubkey << std::endl;
                        if(subsubsubtree.empty()) {
                            std::cout << "subsubsubtree empty" << std::endl;
                            if (auto subsubsubtree_v = subsubsubtree.get_value_optional<double>()) {
                                std::cout << subsubsubtree_v.get() << std::endl;
                            }
                        }
                        else {
                            std::cout << "subsubtree not empty" << std::endl;
                            std::cout << subsubtree.data() << std::endl;
                        }
                    }
                }
            }

        }
    }
    return 0;
}

https://wandbox.org/permlink/uRub7N5VeZ9WrDKd


推荐阅读