boost: просто перебираем элементы дерева - PullRequest
9 голосов
/ 14 апреля 2011

Это должно быть просто (я просто учусь ускорению, поэтому я что-то упускаю)

Я прочитал несколько простых файлов JSON, используя json_read, и теперь у меня есть ptree. Все примеры в Интернете показывают использование ptree.get ("entry_name") для получения записи. Все, что я хочу сделать, это что-то вроде:

 ptree pt;
 read_json(ss,pt);

 BOOST_FOREACH(ptree::value_type &v, pt)
 {
   std::cout << v.{entry_name} << v.{value}
 }

т.е. переберите ptree и запишите каждое имя (то есть то, что вы положили в pt.get ()) и соответствующее ему значение.

Извините, если это просто

Ross

Ответы [ 5 ]

16 голосов
/ 23 мая 2012

Я искал то же самое и нигде не мог найти ответ.На самом деле все оказалось довольно просто:

ptree pt;
/* load/fill pt */
for(iterator iter = pt.begin(); iter != pt.end(); iter++)
{
  std::cout << iter->first << "," << iter->second.data() << std::endl;
}

iter-> first - это имя записи, а iter-> second.data () - это значение записи первого уровня.(Затем вы можете повторить команду iter-> second.begin () / end () для более глубоких уровней.)

Кроме того, если один такой узел в этой итерации не является терминальным и сам по себе является ptreeВы можете получить это как ptree от самого этого итератора: ptree subPt = iter-> second.get_child ("nodeName");

Спасибо, что указали мне направление, теперь ptree выглядит очень интуитивно, как и другиеC ++ stl функции.

2 голосов
/ 18 июля 2011

У меня тоже проблемы с ptree, но, возможно, это поможет: Ознакомьтесь с кратким руководством boost's ptree

v. {ENTRY_NAME}
будет
v.first

и

v. {Значение}
v.second.data ()

Будет ли это работать?

1 голос
/ 15 июня 2018

Старый поток, но вот C ++ 11 версия ответа mr_georg с основанным на диапазоне циклом for:

ptree pt;
/* load/fill pt */
for(auto pair : pt)
{
  std::cout << pair.first << "," << pair.second.data() << std::endl;
}

Для этого JSON:

{
    "key1":"value1",
    "key2":"value2"
}

Это выводит:

key1,value1
key2,value2
1 голос
/ 05 ноября 2012

Вот отличный пример того, как выполнить итерацию ptree, используя BOOST_FOREACH http://akrzemi1.wordpress.com/2011/07/13/parsing-xml-with-boost/

для прямого доступа с использованием обычных функций "get", посмотрите на пример из boost: http://www.boost.org/doc/libs/1_51_0/doc/html/boost_propertytree/tutorial.html

страница документации находится здесь: http://www.boost.org/doc/libs/1_51_0/doc/html/boost/property_tree/basic_ptree.html Я знаю, что она не очень хорошо документирована, но это полезно.

0 голосов
/ 24 марта 2017

Этот пример перебирает простой объект JSON и помещает его значения в вектор.

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/lexical_cast.hpp>

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

int main (void)
{   
    try
    {        
        std::stringstream ss;
        std::string json_obj_str = "{ \"unit_1\": 1, \"unit_2\": 2, \"unit_3\": 3 }";
        std::vector <float> fvec;

        ss << json_obj_str; // put string into stringstream

        boost::property_tree::ptree pt;
        boost::property_tree::read_json(ss, pt);    // put stringstream into property tree

        // iterate over JSON properties
        for (boost::property_tree::ptree::iterator iter = pt.begin(); iter != pt.end(); iter++)
        {
            std::cout << iter->first << ": " << iter->second.data() << std::endl;
            fvec.push_back(boost::lexical_cast<float>(iter->second.data()));
        }

        for (size_t i = 0; i < fvec.size(); i++)
        {
            std::cout << "fvec.at(" << i << ") = " << fvec.at(i) << std::endl;
        }
    }
    catch (const boost::property_tree::ptree_error &e)
    {
        std::cerr << "property_tree error = " << e.what() << std::endl;
        return -2;
    }       
    catch (std::exception const& e)
    {
        std::cerr << "exception = " << e.what() << std::endl;
        return -1;
    }

    return 0;
}
...