Frage

Ich bin wissen, dass er sich nähert, um den Immobilienbaum zu fördern und zu sehen, dass er ein gutes Merkmal von Boost Libs für C ++ - Programmierung ist.

Nun, ich habe einen Zweifel? Wie kann man einen Eigenschaftsbaum mit Iteratoren oder ähnlichem iterieren?

In Bezug auf ein Beispiel für das Durchsuchen des Baumes durch:

BOOST_FOREACH

Aber gibt es nichts weiter? So etwas wie ein STL-ähnlicher Behälter? Es wäre eine bessere Lösung, die über Codequalität sprechen würde ....

War es hilfreich?

Lösung

Boost_forach ist nur eine bequeme Möglichkeit für die Iterierung, die von Iterator, Beginn () und End () durchgeführt werden kann

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

Und in C ++ 11 ist es:

for (auto it: tree)
    ...

Andere Tipps

Hier ist, was ich nach viel Experimenten entwickelt habe. Ich wollte es in der Community teilen, weil ich nicht finden konnte, was ich wollte. Alle schienen nur die Antwort aus den Boost -Dokumenten zu posten, die ich als unzureichend befand. Jedenfalls:

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

Hier ist die Ausgabe:

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

Ich bin kürzlich auf dieses Problem gestoßen und habe die Antworten für mein Bedürfnis unvollständig gefunden, also habe ich mir diesen kurzen und süßen Ausschnitt ausgedacht:

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

Es ist wichtig zu beachten, dass jeder Knoten außer dem Stammknoten sowohl Daten als auch untergeordnete Knoten enthalten kann. Das if (!key.empty()) Bit erhält die Daten für alle außer dem Stammknoten. Wir können auch den Pfad für die Schleife der Kinder des Knotens aufbauen, falls vorhanden.

Sie würden die Parsen durchrufen, indem Sie anrufen parse_tree(root_node, "") Und natürlich müssen Sie etwas in dieser Funktion tun, um es wert zu machen.

Wenn Sie analysieren, wo Sie nicht den vollen Weg benötigen, entfernen Sie einfach die nkey Variable und seine Operationen und einfach passieren it->first zur rekursiven Funktion.

Eine Ergänzung zur Antwort Wie kann man einen Boost -Immobilienbaum iterieren? :

Im C ++ 11 -Stilbereich basiert auf for (auto node : tree), jeder node ist ein std::pair<key_type, property_tree>

Während in der manuell geschriebenen Iteration

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

der Iterator it ist ein Zeiger auf ein solches Paar. Es ist ein kleiner Unterschied in der Nutzung. Zum Beispiel, um auf den Schlüssel zuzugreifen, würde man schreiben it->first aber node.first.

Als neue Antwort gepostet, weil meine vorgeschlagene Bearbeitung auf die ursprüngliche Antwort mit dem Vorschlag, eine neue Antwort zu veröffentlichen, abgelehnt wurde.

BFS -basiertes Print Ptree -Traversal kann verwendet werden, wenn wir eine algorithmische Manipulation durchführen möchten

int print_ptree_bfs(ptree &tree) {
try {
    std::queue<ptree*> treeQ;
    std::queue<string> 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<<itr->first << " " << itr->second.data() << std::endl;
            }
        }

        cout << std::endl;

     }
   } catch (std::exception const& ex) {
    cout << ex.what() << std::endl;
   }
   return EXIT_SUCCESS;
  }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top