How to iterate a boost property tree?

Andry picture Andry · Jan 3, 2011 · Viewed 37.9k times · Source

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....

Answer

Rich picture Rich · Jun 20, 2013

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"
    }
}