Comment itérer un arbre de propriétés boost?

Je sais que je m’approche pour améliorer l’arbre des propriétés et que c’est une bonne fonctionnalité de boost libs pour la programmation c ++.

Eh bien, j’ai un doute? comment itérer une arborescence de propriétés en utilisant des iterators ou similaires?

En référence, il y a juste un exemple de navigation dans l’arborescence à travers:

BOOST_FOREACH 

Mais n’y a-t-il rien de plus? Quelque chose comme un conteneur stl-like? Ce serait une meilleure solution, en parlant de la qualité du code ….

BOOST_FOREACH n’est qu’un moyen pratique pour effectuer une itération pouvant être effectuée par iterator, begin () et end ()

 Your_tree_type::const_iterator end = tree.end(); for (your_tree_type::const_iterator it = tree.begin(); it != end; ++it) ... 

Et en C ++ 11 c’est:

 for (auto it: tree) ... 

Voici ce que je suis venu après beaucoup d’expérimentation. Je voulais le partager dans la communauté parce que je ne pouvais pas trouver ce que je voulais. Tout le monde a semblé simplement poster la réponse de la documentation de relance, que j’ai trouvée insuffisante. De toute façon:

 #include  #include  #include  #include  using namespace std; using boost::property_tree::ptree; ssortingng indent(int level) { ssortingng s; for (int i=0; ifirst << "\": "; printTree(pos->second, level + 1); ++pos; if (pos != pt.end()) { cerr << ","; } cerr << endl; } cerr << indent(level) << " }"; } return; } int main(int, char*[]) { // first, make a json file: string tagfile = "testing2.pt"; ptree pt1; pt1.put("object1.type","ASCII"); pt1.put("object2.type","INT64"); pt1.put("object3.type","DOUBLE"); pt1.put("object1.value","one"); pt1.put("object2.value","2"); pt1.put("object3.value","3.0"); write_json(tagfile, pt1); ptree pt; bool success = true; try { read_json(tagfile, pt); printTree(pt, 0); cerr << endl; }catch(const json_parser_error &jpe){ //do error handling success = false } return success; } 

Voici la sortie:

 rcook@rzbeast (blockbuster): a.out { "object1": { "type": "ASCII", "value": "one" }, "object2": { "type": "INT64", "value": "2" }, "object3": { "type": "DOUBLE", "value": "3.0" } } rcook@rzbeast (blockbuster): cat testing2.pt { "object1": { "type": "ASCII", "value": "one" }, "object2": { "type": "INT64", "value": "2" }, "object3": { "type": "DOUBLE", "value": "3.0" } } 

J’ai récemment rencontré ce problème et j’ai trouvé les réponses incomplètes à mon besoin. J’ai donc créé ce court extrait:

 using boost::property_tree::ptree; void parse_tree(const ptree& pt, std::ssortingng key) { std::ssortingng nkey; if (!key.empty()) { // The full-key/value pair for this node is // key / pt.data() // So do with it what you need nkey = key + "."; // More work is involved if you use a different path separator } ptree::const_iterator end = pt.end(); for (ptree::const_iterator it = pt.begin(); it != end; ++it) { parse_tree(it->second, nkey + it->first); } } 

Il est important de noter que tout nœud, à l’exception du nœud racine, peut contenir des données ainsi que des nœuds enfants. Le bit if (!key.empty()) récupère les données de tous les noeuds sauf le nœud racine. Nous pouvons également commencer à créer le chemin de la boucle des enfants du nœud, le cas échéant.

Vous commenceriez l’parsing en appelant parse_tree(root_node, "") et bien sûr, vous devez faire quelque chose à l’intérieur de cette fonction pour que cela en vaille la peine.

Si vous effectuez une parsing où vous n’avez pas besoin du chemin FULL, supprimez simplement la variable nkey et ses opérations, puis transmettez- it->first à la fonction récursive.

Traversée ptree d’impression basée sur BFS, peut être utilisée si nous voulons faire une manipulation algorithmique

 int print_ptree_bfs(ptree &tree) { try { std::queue treeQ; std::queue strQ; ptree* temp; if (tree.empty()) cout << "\"" << tree.data() << "\""; treeQ.push(&tree); //cout << tree.data(); strQ.push(tree.data()); while (!treeQ.empty()) { temp = treeQ.front(); treeQ.pop(); if (temp == NULL) { cout << "Some thing is wrong" << std::endl; break; } cout << "----- " << strQ.front() << "----- " << std::endl; strQ.pop(); for (auto itr = temp->begin(); itr != temp->end(); itr++) { if (!itr->second.empty()) { //cout << itr->first << std::endl; treeQ.push(&itr->second); strQ.push(itr->first); } else { cout<first << " " << itr->second.data() << std::endl; } } cout << std::endl; } } catch (std::exception const& ex) { cout << ex.what() << std::endl; } return EXIT_SUCCESS; }