2012-01-01 2 views
5

다음 XML 파일이 있으며 아래 구조를 사용하여 저장하려고합니다.부스트 특성 트리가있는 XML 구문 분석

데이터 구조체 :

struct transitions 
    { 
    string oldstate; 
    string event; 
    string newstate; 
    }; 

    struct XML_Diagram 
    { 
    string diag_name; 
    string diag_defaultstate; 
    list<string> diag_states; 
    list<string> diag_events; 
    list<transitions> diag_transitions; 
    }; 

xml 파일 :

<diagram> 
     <diagname>DiagaX</diagname> 
     <states> 
     <state>A</state> 
     .............  
     </states> 
     <events> 
      <event>ev1</event> 
      ................. 
     </events> 
     <defaultstate>A</defaultstate> 
     <transitions> 
      <transition> 
       <oldstate>A</oldstate> 
       <event>ev1</event> 
       <newstate>B</newstate> 
      </transition> 
      <transition> 
       <oldstate>B</oldstate> 
       <event>ev2</event> 
       <newstate>C</newstate> 
      </transition> 
      ......................... 
     </transitions> 
    </diagram> 

그것은 내가 diagram.states에 액세스 할 수있는 방법을 나에게 분명하다. 나는 folowing 코드로 작업을 수행 할 수 있습니다

나에게 분명하지 않다 무엇
using boost::property_tree::ptree; 
    ptree pt; 

    // Get diagram states 
    BOOST_FOREACH(ptree::value_type &v, pt.get_child("diagram.states")) 
    { 
     diag_states.push_back(v.second.data()); 
    } 

내가 레벨 diagram.transitions.transition에서의 데이터에 액세스 할 수있는 방법인가?

제 문제는 문서에서 여러 수준의 복잡한 xml 파일을 구문 분석하는 방법에 대한 예제를 찾을 수 없다는 것입니다.

답변

4

이 유용한 유틸리티 기능은 통과하고 전체 속성 트리 꽤 - 인쇄 다음 v.second 값은 보통 get 방법으로 액세스 할 수있는 나무 자체가

using boost::property_tree::ptree; 

std::string q(const std::string& s) { return "\"" + s + "\""; } 

void print_tree(const ptree& pt, int level) 
{ 
    const std::string sep(2 * level, ' '); 
    BOOST_FOREACH(const ptree::value_type &v, pt) { 
     std::cout 
      << sep 
      << q(v.first) << " : " << q(v.second.data()) << "\n"; 
     print_tree(v.second, level + 1); 
    } 
} 

void print_tree(const ptree& pt) { print_tree(pt, 0); } 

은. 예를 들어 전환 캔은 다음과 같이 액세스 및 인쇄 :이 도움이

namespace pt = boost::property_tree; 

// worker 
typedef std::pair<const pt::ptree&, unsigned> tree_printer; 

// empty ptree helper 
const pt::ptree& empty_ptree() 
{ 
    static pt::ptree t; 
    return t; 
} 


std::ostream& operator <<(std::ostream& os, const tree_printer& p) 
{ 
    const pt::ptree& tree = p.first; 

    if(tree.empty()) return os; 

    const std::string indent(p.second, ' '); 

    BOOST_FOREACH(const pt::ptree::value_type& v, tree) 
    { 
     const std::string& nodeName = v.first; 

     if(nodeName == "<xmlattr>") continue; 

     os << indent << nodeName; 
     const pt::ptree& attributes = 
      v.second.get_child("<xmlattr>", empty_ptree()); 

     if(!attributes.empty()) 
     { 
      os << " [ "; 
      BOOST_FOREACH(const pt::ptree::value_type& attr, attributes) 
      { 
       const std::string& attrName = attr.first; 
       const std::string& attrVal = attr.second.data(); 

       os << attrName << " = '" << attrVal << "'; "; 
      } 
      os << "]"; 
     } 
     os << "\n"; 

     const pt::ptree& childNode = v.second; 
     os << tree_printer(childNode, p.second + 1); 
    } 

    return os; 
} 


std::ostream& operator <<(std::ostream& os, const pt::ptree& tree) 
{ 
    os << tree_printer(tree, 0); 

    return os; 
} 

희망 :

여기
using std::string; 

void print_transitions(const ptree& pt) 
{ 
    BOOST_FOREACH(
     const ptree::value_type &v, 
     pt.get_child("diagram.transitions")) 
    { 
     const ptree& child = v.second; 
     std::cout 
      << "Event " 
      << child.get<string>("event") 
      << " in state " 
      << child.get<string>("oldstate") 
      << " leads to state " 
      << child.get<string>("newstate") 
      << "\n"; 
    } 
} 
4

는 속성으로 ptree을 인쇄하는 방법의 또 다른 예이다.