Подтвердить что ты не робот

Как выполнить итерацию дерева свойств boost?

Я знаю, что подходит для создания дерева свойств и увидел, что это хорошая функция boost libs для программирования на С++.

Ну, у меня есть одно сомнение? как итерации дерева свойств с помощью итераторов или подобных?

В ссылке есть только пример просмотра дерева через:

BOOST_FOREACH

Но ничего больше? Что-то вроде stl-подобного контейнера? Это было бы лучшим решением, говоря о качестве кода....

4b9b3361

Ответ 1

BOOST_FOREACH - это просто удобный способ для итерации, который может выполняться с помощью итератора, begin() и end()

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

И в С++ 11 это:

for (auto it: tree)
    ...

Ответ 2

Вот что я придумал после много экспериментов. Я хотел поделиться им в сообществе, потому что я не мог найти то, что хотел. Кажется, что все просто отправили ответ из документов повышения, которые, как мне показалось, были недостаточными. Во всяком случае:

#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; 
}

Вот результат:

[email protected] (blockbuster): a.out
{
  "object1": 
  {
    "type": "ASCII",
    "value": "one"
   },
  "object2": 
  {
    "type": "INT64",
    "value": "2"
   },
  "object3": 
  {
    "type": "DOUBLE",
    "value": "3.0"
   }
 }
[email protected] (blockbuster): cat testing2.pt 
{
    "object1":
    {
        "type": "ASCII",
        "value": "one"
    },
    "object2":
    {
        "type": "INT64",
        "value": "2"
    },
    "object3":
    {
        "type": "DOUBLE",
        "value": "3.0"
    }
}

Ответ 3

Недавно я столкнулся с этой проблемой и нашел ответы неполными для моей потребности, поэтому я придумал этот короткий и сладкий фрагмент:

using boost::property_tree::ptree;

void parse_tree(const ptree& pt, std::string key)
{
  std::string 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);
  }
}

Важно отметить, что любой node, кроме корня node, может содержать данные, а также дочерние узлы. Бит if (!key.empty()) получит данные для всех, кроме корневого node, мы также можем начать строить путь для цикла для node детей, если они есть.

Вы должны начать синтаксический анализ, вызвав parse_tree(root_node, "") и, конечно же, вам нужно что-то сделать внутри этой функции, чтобы сделать это полезным.

Если вы выполняете парсинг, где вам не нужен полный путь, просто удалите переменную nkey и ее операции и просто передайте it->first в рекурсивную функцию.