2012-01-01 30 views
5

Tôi có tệp XML sau và tôi muốn lưu trữ nó bằng cách sử dụng các cấu trúc bên dưới.Phân tích cú pháp XML với cây thuộc tính tăng cường

các cấu trúc dữ liệu:

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

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

Rõ ràng với tôi làm thế nào tôi có thể truy cập vào diagram.states. tôi có thể làm điều đó với mã 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()); 
    } 

gì không phải là rõ ràng với tôi là làm thế nào tôi có thể truy cập dữ liệu từ tại diagram.transitions.transition mức?

Vấn đề của tôi là tôi không thể tìm thấy bất kỳ ví dụ nào trong tài liệu về cách phân tích các tệp xml phức tạp hơn với nhiều cấp độ.

Trả lời

4

chức năng tiện ích hữu ích này đi qua và khá-in toàn bộ một cây bất động sản:

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

Các v.second giá trị là cây thân có thể được truy cập với get phương pháp thông thường. Các hiệu ứng chuyển tiếp lon ví dụ được truy cập và in như thế này:

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

Dưới đây là một ví dụ về cách in ptree với các thuộc tính:

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

Hope this helps.

Các vấn đề liên quan