2012-05-21 1 views
0

나는 내 문제에 대한 완벽한 해답 인 boost :: property_tree를 발견했습니다. xml 파일에서 특정 데이터를 추출하는 작은 테스트 프로그램을 작성했습니다. 설명서에 제공된 예제를 가이드로 사용했습니다. XML 파일 : test.xml의 :boost :: property_ : tree - 구문 분석 및 데이터 처리

<section> 
    <GROUP> 
     <g_name>ABC</g_name> 
     <fields> 
      <row> 
       <name>A</name> 
       <datatype>string</datatype> 
       <field_size>6</field_size> 
       <value>ABC</value> 
      </row> 
      <row> 
       <name>B</name> 
       <datatype>integer</datatype> 
       <field_size>5</field_size> 
       <value>00107</value> 
      </row> 
      <row> 
       <name>C</name> 
       <datatype>string</datatype> 
       <field_size>20</field_size> 
       <value>LOTS OF LETTERS  </value> 
      </row> 
     </fields> 
    </GROUP> 
    <GROUP> 
     <g_name>CDE</g_name> 
     <fields> 
      <row> 
       <name>A</name> 
       <datatype>string</datatype> 
       <field_size>6</field_size> 
       <value>CDE</value> 
      </row> 
      <row> 
       <name>B</name> 
       <datatype>integer</datatype> 
       <field_size>5</field_size> 
       <value>00100</value> 
      </row> 
      <row> 
       <name>F</name> 
       <datatype>integer</datatype> 
       <field_size>4</field_size> 
       <value>1970</value> 
      </row> 
     </fields> 
    </GROUP> 
</section> 

코드 :

 using boost::property_tree::ptree; 
     struct t_collection 
     { 
      ptree pt; 
      void load(const std::string &filename); 
      void print(); 
     }; 
     void t_collection::load(const std::string &filename) 
     { 
      read_xml(filename, pt); 
     } 
     void t_collection::print() 
     { 
       BOOST_FOREACH(ptree::value_type &v, pt.get_child("section.GROUP")) 
BOOST_FOREACH(ptree::value_type &v, pt.get_child("section.GROUP")) 
{ 
    printf("X: %s->", v.second.data().c_str()); 
    //prints X: ABC -> 
    BOOST_FOREACH(ptree::value_type &w, pt.get_child("section.GROUP.fields.row")) 
     printf("%s\n", w.second.data().c_str()); 
    //prints A, string, 6, ABC - that is good for first iteration but there should be 3 iterations here 
} 
//then prints X: and just "" and repeats the set from the first one 
     } 
     int main() 
     { 
      try 
      { 
       t_collection t1; 
       t1.load("test.xml"); 
       t1.print(); 
      } 
      catch (std::exception &e) 
      { 
       std::cout << "Error: " << e.what() << "\n"; 
      } 
      return 0; 
     } 

참고 : 나는 같은 값 (ABC와 내부 값을 추출하기 위해 노력하고 있어요 - 문자열 - 6 - ABC , 각 그룹에 대해 - 그리고 "행"의 각 집합, 나는 처리하고 다른 형식으로 출력합니다). 제가 시도한 것에 대한 코드 주석을보십시오. 인쇄 내부 (내용() :
지금까지 가장 좋은 결과로했다

BOOST_FOREACH(ptree::value_type &z, pt.get_child("section")) 
    //BOOST_FOREACH(ptree::value_type &v, pt.get_child("section.GROUP")) 
     { 
      printf("X: %s->", pt.get<std::string>("section.GROUP.g_mame", "default").c_str()); 
      //prints X: ABC -> 
      BOOST_FOREACH(ptree::value_type &w, pt.get_child("section.GROUP.fields.row")) 
      { 
       printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.name", "name").c_str()); 
       printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.datatype", "type").c_str()); 
       printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.field_size", "size").c_str()); 
       printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.value", "value").c_str()); 
      } 
     } 
     //prints x: default->A, string, 6, ABC (3 times) then repeat identically 

좀 더 이상의 레코드에서 데이터를 얻을 수없는 나에게 제안을주고, 도와주세요 - 내가 잘못하고있는 무슨을! ?
감사합니다.

답변

2

당신은 당신의 반복의 수준을 누락되었습니다. 당신은 같은 이름을 가진 여러 자녀가있는 요소를 반복해야합니다.

std::pair<ptree::const_assoc_iterator, ptree::const_assoc_iterator> 
    r(pt.get_child("section").equal_range("GROUP")); 

for (ptree::const_assoc_iterator i(r.first); i != r.second; ++i) { 
    // Do something with each group. 
} 

반복 적절 당신이 나무를 내려감에 따라.