Подтвердить что ты не робот

Boost 1.46.1, Дерево свойств: как выполнить итерацию через ptree, получая sub ptrees?

Прежде всего, я скажу, что я думаю, что я понял, как это должно быть сделано, но мой код не будет компилироваться, как я пытаюсь. Я основывал свое предположение на этом официальном примере пустого трюка ptree. Там вы можете найти следующую строку:

  const ptree &settings = pt.get_child("settings", empty_ptree<ptree>());

Что показывает, что это (или должно быть) возможно получить подмножество из ptree.

Итак, я предположил, что мы могли бы итерации через ptree с чем-то вроде BOOST_FOREACH следующим образом:

BOOST_FOREACH(const boost::property_tree::ptree &v,
    config.get_child("servecies"))
{

}

Но я получаю следующую ошибку:

Ошибка 1 Ошибка C2440: 'initializing': невозможно преобразовать из 'std:: pair < _Ty1, _Ty2 > ' в 'const boost:: property_tree:: ptree &'

или если я попробую

BOOST_FOREACH(boost::property_tree::ptree &v,
    config.get_child("servecies", boost::property_tree::empty_ptree<boost::property_tree::ptree>()))
{

}

Я получаю:

Ошибка 1 ошибка C2039: 'empty_ptree': не является членом 'boost:: property_tree'

Итак, что мне делать: как итерации через Boost Ptree и получить sub Ptrees?

Update: Я также пробовал такой код

    BOOST_FOREACH(boost::property_tree::ptree::value_type &v,
    config.get_child("path.to.array_of_objects"))
{
    std::cout << "First data: " << v.first.data() << std::endl;
    boost::property_tree::ptree subtree = (boost::property_tree::ptree) v.second ;
    BOOST_FOREACH(boost::property_tree::ptree::value_type &vs,
        subtree)
    {
        std::cout << "Sub data: " << vs.first.data() << std::endl;
    }
}

Это компилируется, не бросает никаких исключений, но не отключает любой Sub data, он просто просматривает этот цикл.

Обновление 2:

Hm... что-то, вероятно, пошло не так в моем xml - теперь я получаю правильные результаты с этим кодом.

4b9b3361

Ответ 1

Итераторы дерева свойств указывают на пары вида (key, tree) типа ptree::value_type. Таким образом, стандартный цикл для итерации через дочерние элементы node at path выглядит следующим образом:

BOOST_FOREACH(const ptree::value_type &v, pt.get_child(path)) {
    // v.first is the name of the child.
    // v.second is the child tree.
}

Ответ 2

Используя С++ 11, вы можете использовать следующее для повторения всех дочерних элементов node в path:

ptree children = pt.get_child(path);
for (const auto& kv : children) { // kv is of type ptree::value_type
    // v.first is the name of the child
    // v.second is the child tree
}

Ответ 3

У меня была та же проблема с итерацией подложек JSON

boost::property_tree::read_json(streamJSON, ptJSON);

Если у вас есть структура вроде:

{
 playlists: [ {
   id: "1",
   x: "something"
   shows: [
    { val: "test" },
    { val: "test1" },
    { val: "test2" }
   ]
 },
 {
   id: "2"
   x: "else",
   shows: [
    { val: "test3" }
   ]
 }
 ]
}

Вы можете итерировать дочерние узлы:

BOOST_FOREACH(boost::property_tree::ptree::value_type &playlist, ptJSON.get_child("playlists"))
{
    unsigned long uiPlaylistId = playlist.second.get<unsigned long>("id");
    BOOST_FOREACH(boost::property_tree::ptree::value_type &show, playlist.second.get_child("shows."))
    {
       std::string strVal = show.second.get<std::string>("val");
    }
}

Я ничего не мог найти о селекторе путей. для выбора вспомогательного массива. (обратите внимание на точку в конце)

Некоторые хорошие документы можно найти здесь: http://kaalus.atspace.com/ptree/doc/index.html

Надеюсь, это поможет кому-то.