Boost xml 文件解析

Step by step.Just do it. Fighting!

boost中提供了对配置文件读取的支持:property_tree。

property_tree的核心基础是basic_ptree。其接口像std::list。可以执行很多基本的元素操作,比如使用begin()、end()等。此外还加入了操作属性树的get()、get_child()、get_value()、data()等额外的操作。

测试的xml 文件:
SigRaw.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<type>txt</type>
<separator>|</separator>
<fields>
   <field name="start_time_s" id="1" type="u32" len="0" defvalue="0"/>
   <field name="start_time_ns" id="2" type="u32" len="0" defvalue="0" />
</fields>
</root>

SigRaw_CQ.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
   <struct name="bssap" alias="b">
       <rowkey class="com.dinglicom.clouder.decode.cq2.CdrKeyParserImpl">
            <field section="city_code" name="calling_number" id="40" length="4" defvalue="0" />
            <field value="b" name="called_number" id="50" length="8"/>
            <field name="imsi" id="60" type="int" length="11" defvalue="0" decode="hex" placeholder="_" pos_placeholder="head"/>
            <field name="imei" id="70" type="int" length="11" defvalue="0" decode="hex" placeholder="_" pos_placeholder="head"/>
       </rowkey>
       <timestamp class="com.dinglicom.clouder.decode.cq2.McTimestampParserImpl" formula="end_time_s*10+cdr_index">
       </timestamp>
       <indexs>
          <cf name="CALLED_NUMBER" class="com.dinglicom.clouder.decode.cq2.CallednumParserImpl">
                <field name="calling_number" id="10" type="int" length="4" defvalue="0" decode="hex" placeholder="0" pos_placeholder="head"/>
           </cf>
           <cf name="IMSI" class="com.dinglicom.clouder.decode.cq2.ImsiParserImpl">
               <field name="imsi" id="11" type="long" length="8" defvalue="0" decode="hex" placeholder="0" pos_placeholder="head"/>
           </cf>
       </indexs>
       <ag name="AG1">
         <cf name="CF1">
           <cq name="CF1" type="text" seperator=",">
                    <field name="calling_number_str" id="20" type="string" length="24" defvalue="0"/>      
                    <field name="called_number_str" id="30" type="string" length="24" defvalue="0"/>      
               </cq>
               <cq name="CF1" type="bin" seperator="">
                    <field name="calling_number_str" id="30" type="string" length="24" defvalue="0"/>               
                    <field name="called_number_str" id="30" type="string" length="24" defvalue="0"/>               
               </cq>
           </cf>                
       </ag> 
       <ag name="AG2">
         <cf name="CF2">
           <cq name="CF2" type="bin" seperator="">
               <field name="calling_number_str" id="20" type="int" length="4" defvalue="0"/>               
             </cq>
          </cf>                                                                                                  
       </ag>  
    </struct>
</config>
解析代码:
 #include <stdio.h>
#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
using namespace std;
using namespace boost::property_tree;
using namespace boost::property_tree::xml_parser;
int main()
{
   string attrStr = ""; 
   /*cout <<"********SigRaw.xml*************"<<endl;
   ptree pt1;
   read_xml("SigRaw.xml",pt1);
   attrStr = pt1.get<string>("root.type");
   cout << "attrStr:type---" << attrStr << endl;
   attrStr = pt1.get<string>("root.separator");
   cout << "attrStr:separator---" << attrStr << endl;
   BOOST_FOREACH(ptree::value_type& v, pt1.get_child("root.fields"))
   {   
       attrStr = v.second.get<string>("<xmlattr>.name");
       cout << "attrStr:name---" << attrStr << endl;
       attrStr = v.second.get<string>("<xmlattr>.id");
       cout << "attrStr:id---" << attrStr << endl;
       attrStr = v.second.get<string>("<xmlattr>.type");
       cout << "attrStr:type---" << attrStr << endl;
       attrStr = v.second.get<string>("<xmlattr>.len");
       cout << "attrStr:len---" << attrStr << endl;
       attrStr = v.second.get<string>("<xmlattr>.defvalue");
       cout << "attrStr:defvalue---" << attrStr << endl;
   }
   */
   cout <<"********SigRaw_CQ.xml*************"<<endl;
   ptree pt2;
   read_xml("SigRaw_CQ.xml",pt2);
   
   BOOST_FOREACH(ptree::value_type& v, pt2.get_child("config.struct"))
   {
  //cout << "v.first: " << v.first << endl; 
  if(v.first == "<xmlattr>"){  
  attrStr = v.second.get<string>("name");
  cout << "attrStr:struct name---" << attrStr << endl;  
  attrStr = v.second.get<string>("alias");
  cout << "attrStr:struct alias---" << attrStr << endl;
  }
  else if (v.first == "rowkey")
  {
BOOST_FOREACH(ptree::value_type &v1, v.second)
{
if (v1.first == "<xmlattr>")
{
attrStr = v1.second.get<string>("class");
cout << "attrStr:rowkey class---" << attrStr << endl;
}
else
{
//section
try
{
attrStr = v1.second.get<string>("<xmlattr>.section");
cout << "attrStr:field section---" << attrStr << endl;
}
catch (...)
{  
}
//value
try
{
attrStr = v1.second.get<string>("<xmlattr>.value");
cout << "attrStr:field value---" << attrStr << endl;
}
catch (...)
{
}
//normal
try
{
attrStr = v1.second.get<string>("<xmlattr>.name");
cout << "attrStr:field name---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.id");
cout << "attrStr:field id---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.length");
cout << "attrStr:field length---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.defvalue");
cout << "attrStr:field defvalue---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.type");
cout << "attrStr:field type---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.decode");
cout << "attrStr:field decode---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.placeholder");
cout << "attrStr:field placeholder---" << attrStr << endl;
attrStr = v1.second.get<string>("<xmlattr>.pos_placeholder");
cout << "attrStr:field pos_placeholder---" << attrStr << endl;
}
catch (...)
{
}
}
}
  }
  else if(v.first == "timestamp")
  {
  attrStr = v.second.get<string>("<xmlattr>.class");
  cout << "attrStr:timestamp class---" << attrStr << endl;
  attrStr = v.second.get<string>("<xmlattr>.formula");
  cout << "attrStr:timestamp formula---" << attrStr << endl;
  }
  else if(v.first == "indexs")
  {
  BOOST_FOREACH(ptree::value_type &v1, v.second)
  {  
  attrStr = v1.second.get<string>("<xmlattr>.name");
  cout << "attrStr:indexs cf name---" << attrStr << endl;
  attrStr = v1.second.get<string>("<xmlattr>.class");
  cout << "attrStr:indexs cf class---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.name");
  cout << "attrStr:field name---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.id");
  cout << "attrStr:field id---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.type");
  cout << "attrStr:field type---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.length");
  cout << "attrStr:field length---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.defvalue");
  cout << "attrStr:field defvalue---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.decode");
  cout << "attrStr:field decode---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.placeholder");
  cout << "attrStr:field placeholder---" << attrStr << endl;
  attrStr = v1.second.get<string>("field.<xmlattr>.pos_placeholder");
  cout << "attrStr:field pos_placeholder---" << attrStr << endl;
  }//end BOOST_FOREACH 
  }
  else if(v.first == "ag")
  {
  BOOST_FOREACH(ptree::value_type &v1, v.second)
  {  
  //cout << "v1.first: " << v1.first << endl;
  if(v1.first == "<xmlattr>"){    
  attrStr = v1.second.get<string>("name");
  cout << "attrStr:ag name---" << attrStr << endl; 
  }  
  else
  {  
  BOOST_FOREACH(ptree::value_type &v2, v1.second)
  {  
  //cout << "v2.first: " << v2.first << endl;
  if(v2.first == "<xmlattr>"){   
  attrStr = v2.second.get<string>("name");
  cout << "attrStr:cf name---" << attrStr << endl;  
  }  
  else
  {  
  BOOST_FOREACH(ptree::value_type &v3, v2.second)
  { 
  //cout << "v3.first: " << v3.first << endl; 
  if(v3.first == "<xmlattr>"){  //it's an attribute  
  attrStr = v3.second.get<string>("name");
  cout << "attrStr:cq name---" << attrStr << endl;
  attrStr = v3.second.get<string>("type");
  cout << "attrStr:cq type---" << attrStr << endl;
  attrStr = v3.second.get<string>("seperator");
  cout << "attrStr:cq seperator---" << attrStr << endl;  
  }  
  else
  {  
  attrStr = v3.second.get<string>("<xmlattr>.name");
  cout << "attrStr:field name---" << attrStr << endl;
  attrStr = v3.second.get<string>("<xmlattr>.id");
  cout << "attrStr:field id---" << attrStr << endl;
  attrStr = v3.second.get<string>("<xmlattr>.type");
  cout << "attrStr:field type---" << attrStr << endl;
  attrStr = v3.second.get<string>("<xmlattr>.length");
  cout << "attrStr:field length---" << attrStr << endl;
  attrStr = v3.second.get<string>("<xmlattr>.defvalue");
  cout << "attrStr:field defvalue---" << attrStr << endl;
  }  
  }//end BOOST_FOREACH 
  }  
  }//end BOOST_FOREACH    
  }  
  }//end BOOST_FOREACH 
   }     
   }//end BOOST_FOREACH
   
   return 0;
}


运行结果:

 [root@hyt1 boost_xml_parser]# g++ -o xml_parser_test xml_parser_test.cpp

[root@hyt1 boost_xml_parser]# ./xml_parser_test

********SigRaw_CQ.xml*************

attrStr:struct name---bssap

attrStr:struct alias---b

attrStr:rowkey class---com.dinglicom.clouder.decode.cq2.CdrKeyParserImpl

attrStr:field section---city_code

attrStr:field name---calling_number

attrStr:field id---40

attrStr:field length---4

attrStr:field defvalue---0

attrStr:field value---b

attrStr:field name---called_number

attrStr:field id---50

attrStr:field length---8

attrStr:field name---imsi

attrStr:field id---60

attrStr:field length---11

attrStr:field defvalue---0

attrStr:field type---int

attrStr:field decode---hex

attrStr:field placeholder---_

attrStr:field pos_placeholder---head

attrStr:field name---imei

attrStr:field id---70

attrStr:field length---11

attrStr:field defvalue---0

attrStr:field type---int

attrStr:field decode---hex

attrStr:field placeholder---_

attrStr:field pos_placeholder---head

attrStr:timestamp class---com.dinglicom.clouder.decode.cq2.McTimestampParserImpl

attrStr:timestamp formula---end_time_s*10+cdr_index

attrStr:indexs cf name---CALLED_NUMBER

attrStr:indexs cf class---com.dinglicom.clouder.decode.cq2.CallednumParserImpl

attrStr:field name---calling_number

attrStr:field id---10

attrStr:field type---int

attrStr:field length---4

attrStr:field defvalue---0

attrStr:field decode---hex

attrStr:field placeholder---0

attrStr:field pos_placeholder---head

attrStr:indexs cf name---IMSI

attrStr:indexs cf class---com.dinglicom.clouder.decode.cq2.ImsiParserImpl

attrStr:field name---imsi

attrStr:field id---11

attrStr:field type---long

attrStr:field length---8

attrStr:field defvalue---0

attrStr:field decode---hex

attrStr:field placeholder---0

attrStr:field pos_placeholder---head

attrStr:ag name---AG1

attrStr:cf name---CF1

attrStr:cq name---CF1

attrStr:cq type---text

attrStr:cq seperator---,

attrStr:field name---calling_number_str

attrStr:field id---20

attrStr:field type---string

attrStr:field length---24

attrStr:field defvalue---0

attrStr:field name---called_number_str

attrStr:field id---30

attrStr:field type---string

attrStr:field length---24

attrStr:field defvalue---0

attrStr:cq name---CF1

attrStr:cq type---bin

attrStr:cq seperator---

attrStr:field name---calling_number_str

attrStr:field id---30

attrStr:field type---string

attrStr:field length---24

attrStr:field defvalue---0

attrStr:field name---called_number_str

attrStr:field id---30

attrStr:field type---string

attrStr:field length---24

attrStr:field defvalue---0

attrStr:ag name---AG2

attrStr:cf name---CF2

attrStr:cq name---CF2

attrStr:cq type---bin

attrStr:cq seperator---

attrStr:field name---calling_number_str

attrStr:field id---20

attrStr:field type---int

attrStr:field length---4

attrStr:field defvalue---0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shinobi_Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值