2011-01-03 2 views
17

속성 트리를 높이기 위해 접근하고 C++ 프로그래밍을위한 부스트 라이브러리의 좋은 기능이라고 생각했습니다.부스트 특성 트리를 반복하는 방법은 무엇입니까?

음, 한 가지 의심의 여지가 있습니까? 반복자 또는 유사 항목을 사용하여 속성 트리를 반복하는 방법? 참조에서

을 통해 트리를 탐색의 단지 예를 들어 있습니다 :

BOOST_FOREACH 

그러나 아무것도 더 없다? stl과 같은 용기 같은 것? 그것은

답변

15

BOOST_FOREACH가) (

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

그리고에를 (시작)과 끝 반복자에 의해 수행 할 수 있습니다 반복하는 단지 편리한 방법입니다 .... 코드 품질에 대해 말하기, 더 나은 해결책이 될 것입니다 C++ 11 it 's :

+0

오후에 테스트 해 보겠습니다 ... 아, 너무 쉬웠다 고 생각하지 않았어요. 곧 알려 드리겠습니다. :) – Andry

+0

괜찮 으면서도 반복기는 .... 반복하는 부분은 무엇입니까? ???? ptree ??? – Andry

+1

ptree의 최상위 레벨로, 반복적으로이 작업을 수행해야하는 모든 나뭇잎을 반복 할 수 있습니다. –

25

다음은 많은 실험을 통해 생각해 낸 것입니다. 내가 원했던 것을 찾을 수 없어 공동체에서 공유하고 싶었습니다. 모두가 내가 부적절하다고 생각한 부스트 문서에서 대답을 게시하는 것처럼 보였습니다. 어쨌든 : 여기

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

나는 최근이 문제에 달려 내 필요에 대한 불완전한 해답을 발견, 그래서 나는이 짧은 달콤한 조각 해낸 :

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

루트 노드를 제외한 모든 노드에는 자식 노드뿐만 아니라 데이터도 포함될 수 있습니다. if (!key.empty()) 비트는 루트 노드를 제외한 모든 노드의 데이터를 가져오고, 노드의 자식 노드가있는 경우 루핑 경로를 구축하기 시작할 수도 있습니다.

parse_tree(root_node, "")을 호출하여 구문 분석을 시작할 수 있습니다. 물론이 작업을 수행하기 위해서는이 함수 내부에서 수행해야합니다.

전체 경로가 필요하지 않은 구문 분석을 수행하려면 nkey 변수와 그 연산을 제거하고 it->first을 재귀 함수에 전달하기 만하면됩니다.