Увеличить дерево свойств, получая элемент из неименованного массива - PullRequest
0 голосов
/ 30 мая 2018

У меня есть следующий файл json

[  
   {  
      "a":5855925.424944928,
      "b":0,
      "c":96,
      "d":2096640,
      "e":0
   }
]

Я делаю это,

    boost::property_tree::ptree jsontree;
    std::stringstream ss;
    ss << "[{\"a\": 5855925.424944928, \"b\": 0, \"c\": 96, \"d\": 2096640, \"e\": 0}]";
    boost::property_tree::read_json(ss, jsontree);
    // get the children, i.e. the list elements
    auto bounds = jsontree.equal_range("");
    std::cout << "Size of list : " << std::distance( bounds.first, bounds.second ) << "\n";

Но я не знаю, как прочитать это из дерева свойств (например: get<float>("a"), get<int>("c"))?

Любая помощь будет принята с благодарностью.

Спасибо

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Вы можете использовать BOOST_FOREACH для этого.Я прилагаю некоторый код, но они основаны на xml_data.Но вы можете использовать подобное для получения каждого значения, не зная ключа.

 BOOST_FOREACH(pt::ptree::value_type &v, tree) {


    std::string at = v.first + ATTR_SET;

    std::cout << "Extracting attributes from " << at << ":\n";

    BOOST_FOREACH(pt::ptree::value_type &v2,v.second.get_child("<xmlattr>")){
        std::cout<<""<<v2.first.data()<<" : " <<v2.second.data()<<"\n";
    }

    std::cout<<"now in book\n";
    BOOST_FOREACH(pt::ptree::value_type &v3,tree.get_child("bookstore."+v.first)){
        std::cout<<""<<v3.first.data()<<" : " <<v3.second.data()<<"\n";
    }




    m_modules.insert(v.second.data());


}

здесь дерево - boost :: Property_tree :: ptree

0 голосов
/ 30 мая 2018

Примечание: массивы верхнего уровня на самом деле не поддерживаются (вы не можете использовать их в обратном порядке с помощью дерева свойств Boost).

Ограничения описаны в документации

Сохранение этого же дерева приведет к потере всей информации о типе и преобразованию массива в следующее:

{
    "": {
        "a": "5855925.424944928",
        "b": "0",
        "c": "96",
        "d": "2096640",
        "e": "0"
    }
}

Массивы - это "объекты с пустыми ключами".Вы, кажется, уже знали это, судя по вашему образцу.Итак, просто используйте его:

for (auto& object_node : boost::make_iterator_range(jsontree.equal_range(""))) {
    ptree const& object = object_node.second;
    std::cout << "a: " << object.get<double>("a") << "\n";
    std::cout << "b: " << object.get<int>("b") << "\n";
    std::cout << "c: " << object.get<int>("c") << "\n";
    std::cout << "d: " << object.get<int>("d") << "\n";
    std::cout << "e: " << object.get<int>("e") << "\n";
}

Улучшенная демоверсия

Часто приятнее извлекать некоторые типы / функции:

Live OnColiru

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

using boost::property_tree::ptree;

struct Object {
    double a;
    int b, c, d, e;

    friend std::ostream& operator<<(std::ostream& os, Object const& object) {
        return os << "a: " << object.a << "\n"
                  << "b: " << object.b << "\n"
                  << "c: " << object.c << "\n"
                  << "d: " << object.d << "\n"
                  << "e: " << object.e << "\n";
    }

    static Object parse(ptree const& from) {
        return {
            from.get<double>("a"),
            from.get<int>("b"),
            from.get<int>("c"),
            from.get<int>("d"),
            from.get<int>("e"),
        };
    }
};

int main() {
    boost::property_tree::ptree jsontree;
    {
        std::stringstream ss(R"([{"a": 5855925.424944928, "b": 0, "c": 96, "d": 2096640, "e": 0}])");
        boost::property_tree::read_json(ss, jsontree);
    }

    for (auto& object_node : boost::make_iterator_range(jsontree.equal_range(""))) {
        std::cout << Object::parse(object_node.second);
    }
}

Отпечатки

a: 5.85593e+06
b: 0
c: 96
d: 2096640
e: 0
...