Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate a boost property tree?

I am know approaching to boost property tree and saw that it is a good feature of boost libs for c++ programming.

Well, I have one doubt? how to iterate a property tree using iterators or similar?

In reference there is just an example of browsing the tree through:

BOOST_FOREACH 

But is there nothing more? Something like an stl-like container? It would be a better solution, speaking about code quality....

like image 935
Andry Avatar asked Jan 03 '11 17:01

Andry


2 Answers

Here is what I came up with after much experimentation. I wanted to share it in the community because I couldn't find what I wanted. Everybody seemed to just post the answer from the boost docs, which I found to be insufficient. Anyhow:

#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/json_parser.hpp> #include <string> #include <iostream>  using namespace std;  using boost::property_tree::ptree;   string indent(int level) {   string s;    for (int i=0; i<level; i++) s += "  ";   return s;  }   void printTree (ptree &pt, int level) {   if (pt.empty()) {     cerr << "\""<< pt.data()<< "\"";   }    else {     if (level) cerr << endl;       cerr << indent(level) << "{" << endl;           for (ptree::iterator pos = pt.begin(); pos != pt.end();) {       cerr << indent(level+1) << "\"" << pos->first << "\": ";         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;  } 

Here is the output:

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"     } } 
like image 142
Rich Avatar answered Oct 06 '22 00:10

Rich


BOOST_FOREACH is just a convenient way for iterating that can be done by iterator, begin() and end()

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

And since C++11 it's:

for (auto& it: tree)     ... 
like image 39
Andriy Tylychko Avatar answered Oct 06 '22 00:10

Andriy Tylychko