Boost 1.46.1, Дерево свойств: Как перебрать ветки дерева, получая поддерево? - PullRequest
30 голосов
/ 12 июля 2011

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

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

, которая показывает, что можно (или должно быть) получить поддерево из дерева.

Так что я предположил, что мы можем перебрать что-то через дерево с чем-токак BOOST_FOREACH таким образом:

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

}

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

Ошибка 1 ошибка C2440: «инициализация»: невозможно преобразовать из «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?

Обновление: Я также пробовал такой код

    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:

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

Ответы [ 3 ]

31 голосов
/ 12 июля 2011

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

25 голосов
/ 06 декабря 2013

Используя C ++ 11, вы можете использовать следующее для перебора всех дочерних узлов в 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
}
5 голосов
/ 31 декабря 2012

У меня была та же проблема с итерацией через узлы 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

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

...