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 - теперь я получаю правильные результаты с этим кодом.
Ответы
Ответ 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
Надеюсь, это поможет кому-то.