zoukankan      html  css  js  c++  java
  • boost::xml——基本操作以及中文乱码解决方案

    下面是本人使用boost库的xml部分的基础操作,并且解决对于大家使用boost库读写中文xml内容出现的乱码问题。

    1.实现boost库xml基本操作
    2.解决boost对xml中中文乱码问题
    3.实现普通字符串和宽字符串的傻瓜切换(模仿tchar.h)
    4.代码运行环境为VS2010,需要导入boost库才能正常运行
    5.VS2010运行时可能会发生错误。例如:cl.exe 或者 cvtres.exe 报错。 解决办法就是重新打开项目或者切换其它正常项目运行一下(反正我是这么解决的)

    下面是源码部分。

    注:为了说明问题使用一个cpp文件完成所有操作。

      1 /*实现单字节和宽字节的自动转换*/
      2 
      3 //note_1: G prefix is global meaning
      4 //note_2: template<typename type> ,type only support tstring, can't support int and so on.
      5 //note_3: In VS2010 update1, it maybe encounter bug for VS2010 self. example: "error MSB6006: CL.exe" or "LINK : fatal error LNK1158: cvtres.exe", solution is reopen project
      6 //note_4: switch std::string and std::wstring in use macro CHINESE_CHARSET. The major solution is chinese unreadable code with xml file
      7 
      8 //Windows API
      9 //#include <tchar.h>
     10 //#include <wchar.h>
     11 
     12 //C++ standard template library
     13 #include <iostream>
     14 #include <string>
     15 #include <exception>
     16 #include <map>
     17 
     18 //third library head files
     19 #include <boost/property_tree/ptree.hpp>
     20 #include <boost/property_tree/xml_parser.hpp>
     21 #include <boost/program_options/detail/convert.hpp>
     22 #include <boost/program_options/detail/utf8_codecvt_facet.hpp>
     23 #include <boost/foreach.hpp>
     24 
     25 using namespace std;
     26 using namespace boost;
     27 using namespace boost::property_tree;
     28 
     29 
     30 #define CHINESE_CHARSET //控制处理宽字符还是单字节字符,其中宽字符可以对中文进行支持
     31 
     32 #ifdef CHINESE_CHARSET
     33 #define tptree boost::property_tree::wptree
     34 #define tstring std::wstring
     35 #define _USERT(x) L ## x
     36 #else
     37 #define tptree boost::property_tree::ptree
     38 #define tstring std::string
     39 #define _USERT(x) x
     40 #endif
     41 
     42 bool LoadXML(tptree &o_pt, const string i_strFileName)
     43 {
     44     //set locale
     45 #ifdef CHINESE_CHARSET
     46     std::locale current_locale(locale(""), new boost::program_options::detail::utf8_codecvt_facet());
     47 #else
     48     std::locale current_locale;
     49 #endif
     50 
     51     //read xml
     52     try
     53     {
     54         boost::property_tree::read_xml(i_strFileName, o_pt, boost::property_tree::xml_parser::trim_whitespace, current_locale);
     55     }
     56     catch (const std::exception &e)
     57     {
     58         cout << "Error:" << typeid(e).name() << ": ";
     59         cout << e.what() << endl;
     60         return false;
     61     }
     62     
     63     return true;
     64 }
     65 
     66 bool SaveXML(const tptree &i_pt, const string i_strFileName)
     67 {
     68     //set locale
     69 #ifdef CHINESE_CHARSET
     70     std::locale current_locale(locale(""), new boost::program_options::detail::utf8_codecvt_facet());
     71     boost::property_tree::xml_parser::xml_writer_settings<wchar_t> settings(L'	', 1, L"utf-8");
     72 #else
     73     std::locale current_locale;
     74     boost::property_tree::xml_parser::xml_writer_settings<char> settings('	', 1, "utf-8");
     75 #endif
     76 
     77     try
     78     {
     79         boost::property_tree::write_xml(i_strFileName, i_pt, current_locale, settings);
     80     }
     81     catch (const std::exception &e)
     82     {
     83         cout << "Error:" << typeid(e).name() << ": ";
     84         cout << e.what() << endl;
     85         return false;
     86     }
     87 
     88     return true;
     89 }
     90 
     91 //是否存在直接子节点或者属性,返回-1:出现错误;返回0:没有子节点或者属性;返回1:有属性或者有子节点
     92 int IsExistChildNode(const tptree &i_pt, const tstring i_strNodePath)
     93 {
     94     try
     95     {
     96         const tptree pt = i_pt.get_child(i_strNodePath);
     97         if (pt.empty())
     98         {
     99             return 0; //no child
    100         }
    101         else
    102         {
    103             return 1; //have child or attribute
    104         }
    105     }
    106     catch (const std::exception &e)
    107     {
    108         cout << "Error:" << typeid(e).name() << ": ";
    109         cout << e.what() << endl;
    110         return -1; //error: exception
    111     }
    112 
    113     return -1;
    114 }
    115 
    116 //查看是否有子节点或者属性,如果没有则返回false,如果有则返回true
    117 //通过o_nChildNodeCount和o_nChildNodeAttributeCount返回数目
    118 //通过o_bChildNodeOrAttribute判断是直接子节点还是属性:true直接子节点;false属性
    119 bool IsChildNodeOrAttr(const tptree &i_pt
    120     , const tstring i_strNodePath
    121     , bool &o_bChildNodeOrAttribute
    122     , int &o_nChildNodeCount //直接子节点数目
    123     , int &o_nChildNodeAttributeCount) //直接子节点属性数目
    124 {
    125     o_bChildNodeOrAttribute = false; //initialize
    126     o_nChildNodeCount = 0; //initialize child node count
    127     o_nChildNodeAttributeCount = 0; //initialize attribute count
    128 
    129     tstring l_strChildNode; //local object
    130     tstring l_strXmlAttr(_USERT("<xmlattr>")); //with l_strChildNode
    131     tstring l_strAttrPath(_USERT(".<xmlattr>")); //mark <xmlattr>
    132     bool l_bflag = true; //valve
    133 
    134     try
    135     {
    136         int l_bExistChildNode = IsExistChildNode(i_pt, i_strNodePath);
    137         if (0==l_bExistChildNode)
    138         {
    139             return false; //no child node or attribute
    140         }
    141         BOOST_FOREACH (const tptree::value_type &v, i_pt.get_child(i_strNodePath))
    142         {
    143             l_strChildNode = v.first.data();
    144             if (l_strChildNode==l_strXmlAttr && true==l_bflag)
    145             {
    146                 BOOST_FOREACH (const tptree::value_type &v, i_pt.get_child(i_strNodePath+l_strAttrPath))
    147                 {
    148                     ++o_nChildNodeAttributeCount;
    149                     o_bChildNodeOrAttribute = false; //is attribute
    150                 }
    151                 l_bflag = false;
    152             }
    153             else
    154             {
    155                 ++o_nChildNodeCount;
    156                 o_bChildNodeOrAttribute = true; //is child node
    157             }
    158         }
    159         return true;
    160     }
    161     catch (const std::exception &e)
    162     {
    163         cout << "Error:" << typeid(e).name() << ": ";
    164         cout << e.what() << endl;
    165         return false; //error: exception
    166     }
    167 
    168     return false;
    169 }
    170 
    171 //返回获取直接子节点是否完成:false:获取失败;true:获取成功
    172 //获取的直接子节点保存在o_mapChildNode容器中
    173 //注意:使用前请先确认是否有直接子节点,可以调用IsChildNodeOrAttr查看o_bChildNodeOrAttribute
    174 template<typename type> bool GetChildNodes(const tptree &i_pt, const tstring i_strNodePath, multimap<tstring, type> &o_mmapChildNodes)
    175 {
    176     tstring l_strChildNode;
    177     tstring l_strXmlAttr(_USERT("<xmlattr>")); //with l_strChildNode
    178     type l_tpChildNodeValue;
    179 
    180     try
    181     {
    182         int l_bExistChildNode = IsExistChildNode(i_pt, i_strNodePath);
    183         if (0==l_bExistChildNode)
    184         {
    185             return false; //no child node or attribute
    186         }
    187         BOOST_FOREACH (const tptree::value_type &v, i_pt.get_child(i_strNodePath))
    188         {
    189             l_strChildNode = v.first.data();
    190             l_tpChildNodeValue = v.second.get_value<type>();
    191             if (0!=l_strChildNode.compare(l_strXmlAttr))
    192             {
    193                 o_mmapChildNodes.insert(pair<tstring, type>(l_strChildNode, l_tpChildNodeValue));
    194             }
    195             else
    196             {
    197                 throw runtime_error("This node include with attribute.
    Please call IsChildNodeOrAttr function before.");
    198             }
    199         }
    200     }
    201     catch (const std::exception &e)
    202     {
    203         cout << "Error:" << typeid(e).name() << ": ";
    204         cout << e.what() << endl;
    205         return false; //error: exception
    206     }
    207 
    208     return false;
    209 }
    210 
    211 //返回获取当前节点属性是否完成:false:获取失败;true:获取成功
    212 //获取的当前节点属性保存在o_mapCurrentNodeAttrs容器中
    213 //注意:使用前请先确认当前节点是否有属性,可以调用IsChildNodeOrAttr查看o_bChildNodeOrAttribute
    214 template<typename type> bool GetCurrentNodeAttrs(const tptree &i_pt, const tstring i_strNodePath, map<tstring, type> &o_mapCurrentNodeAttrs)
    215 {
    216     tstring l_strChildNodeAttr;
    217     tstring l_strXmlAttr(_USERT("<xmlattr>")); //with l_strChildNode
    218     tstring l_strAttrPath(_USERT(".<xmlattr>")); //mark <xmlattr>
    219     type l_tpChildNodeAttrValue;
    220 
    221     try
    222     {
    223         int l_bExistChildNode = IsExistChildNode(i_pt, i_strNodePath);
    224         if (0==l_bExistChildNode)
    225         {
    226             return false; //no child node or attribute
    227         }
    228         if (l_strXmlAttr==i_pt.get_child(i_strNodePath).begin()->first.data())
    229         {
    230             BOOST_FOREACH (const tptree::value_type &v, i_pt.get_child(i_strNodePath+l_strAttrPath))
    231             {
    232                 l_strChildNodeAttr = v.first.data();
    233                 l_tpChildNodeAttrValue = v.second.get_value<type>();
    234                 o_mapCurrentNodeAttrs.insert(pair<tstring, type>(l_strChildNodeAttr, l_tpChildNodeAttrValue));
    235             }
    236             return true;
    237         }
    238         else
    239         {
    240             throw runtime_error("This node exclude with attribute.
    Please call IsChildNodeOrAttr function before.");
    241         }
    242     }
    243     catch (const std::exception &e)
    244     {
    245         cout << "Error:" << typeid(e).name() << ": ";
    246         cout << e.what() << endl;
    247         return false; //error: exception
    248     }
    249 
    250     return false;
    251 }
    252 
    253 //返回获取当前节点的直接子节点属性是否完成:false:获取失败;true:获取成功
    254 //获取的当前节点的直接子节点属性保存在o_mapChildNodesAttr容器中
    255 //注意:使用前请先确认当前节点的直接子节点是否有属性,可以调用IsChildNodeOrAttr查看o_bChildNodeOrAttribute
    256 //注意:本功能只应用在当前节点的多个直接子节点具有相同节点名的情况,对于多个直接子节点具有不同节点名情况不适用
    257 template<typename type> bool GetChildNodesAttrs(const tptree &i_pt, const tstring i_strNodePath, multimap<tstring, map<tstring, type>> &o_mmapChildNodesAttrs)
    258 {
    259     tstring l_strChildNode;
    260     tstring l_strChildNodeAttr;
    261     type l_tpChildNodeAttrValue;
    262     tstring l_strXmlAttr(_USERT("<xmlattr>")); //with l_strChildNode
    263     tstring l_strAttrPath(_USERT(".<xmlattr>")); //mark <xmlattr>
    264 
    265     try
    266     {
    267         int l_bExistChildNode = IsExistChildNode(i_pt, i_strNodePath); //check child node
    268         if (0==l_bExistChildNode)
    269         {
    270             return false; //no child node
    271         }
    272 
    273         //tstring l_strChildNode = i_pt.get_child(i_strNodePath).begin()->first.data();
    274         tstring l_strChildNode = i_pt.get_child(i_strNodePath).front().first.data();
    275         tstring l_strChildNodeAttrPath = i_strNodePath+_USERT(".")+l_strChildNode+l_strAttrPath;
    276         int l_bExistChildNodeAttr = IsExistChildNode(i_pt, l_strChildNodeAttrPath); //check child node attribute
    277         if (0==l_bExistChildNodeAttr)
    278         {
    279             return false; //no child node attribute
    280         }
    281 
    282         BOOST_FOREACH (const tptree::value_type &v, i_pt.get_child(i_strNodePath))
    283         {
    284             map<tstring, type> l_mapChildNodeAttrs;
    285             l_strChildNode = v.first.data();
    286             BOOST_FOREACH (const tptree::value_type &subv, v.second.get_child(l_strXmlAttr))
    287             {
    288                 l_strChildNodeAttr = subv.first.data();
    289                 l_tpChildNodeAttrValue = subv.second.get_value<type>();
    290                 l_mapChildNodeAttrs.insert(pair<tstring, type>(l_strChildNodeAttr, l_tpChildNodeAttrValue));
    291             }
    292             o_mmapChildNodesAttrs.insert(pair<tstring, map<tstring, type>>(l_strChildNode, l_mapChildNodeAttrs));
    293         }
    294         return true;
    295     }
    296     catch (const std::exception &e)
    297     {
    298         cout << "Error:" << typeid(e).name() << ": ";
    299         cout << e.what() << endl;
    300         return false; //error: exception
    301     }
    302 
    303     return false;
    304 }
    305 
    306 //提供指向指定节点的可读写迭代器io_iter,使用i_strNodeValue修改指定节点的值
    307 bool SetCurrentNodeValue(tptree::iterator io_iter, const tstring i_strNodeValue)
    308 {
    309     try
    310     {
    311         io_iter->second.put_value<tstring>(i_strNodeValue);
    312         return true;
    313     }
    314     catch (const std::exception &e)
    315     {
    316         cout << "Error:" << typeid(e).name() << ": ";
    317         cout << e.what() << endl;
    318         return false; //error: exception
    319     }
    320 
    321     return false;
    322 }
    323 
    324 //提供指向指定节点属性的可读写迭代器io_iter,使用i_strNodeAttrValue修改指定节点的值
    325 bool SetCurrentNodeAttrValue(tptree::iterator io_iter, const tstring i_strNodeAttrValue)
    326 {
    327     try
    328     {
    329         io_iter->second.put_value<tstring>(i_strNodeAttrValue);
    330         return true;
    331     }
    332     catch (const std::exception &e)
    333     {
    334         cout << "Error:" << typeid(e).name() << ": ";
    335         cout << e.what() << endl;
    336         return false; //error: exception
    337     }
    338 
    339     return false;
    340 }
    341 
    342 //提供指向指定节点的迭代器io_iter,将该节点删除
    343 //节点io_pt就是迭代器io_iter指定的节点本身
    344 //注:也可以删除节点属性,删除属性请使用<xmlattr>
    345 bool DelCurrentNode(tptree &io_pt, tptree::iterator i_iter)
    346 {
    347     try
    348     {
    349         io_pt.erase(i_iter);
    350         return true;
    351     }
    352     catch (const std::exception &e)
    353     {
    354         cout << "Error:" << typeid(e).name() << ": ";
    355         cout << e.what() << endl;
    356         return false; //error: exception
    357     }
    358 
    359     return false;
    360 }
    361 
    362 //当前节点io_pt
    363 //将该节点以及所有具有相同节点名字节点删除
    364 //注:也可以删除节点属性,删除属性请使用<xmlattr>
    365 tptree::size_type DelCurrentNodes(tptree &io_pt, const tstring &i_strChildNode)
    366 {
    367     try
    368     {
    369         return io_pt.erase(i_strChildNode);
    370     }
    371     catch (const std::exception &e)
    372     {
    373         cout << "Error:" << typeid(e).name() << ": ";
    374         cout << e.what() << endl;
    375         return -1; //error: exception
    376     }
    377 
    378     return -1;
    379 }
    380 
    381 
    382 void main()
    383 {
    384     //test code
    385     string l_strFileName1("F:\Desktop\20140411\测试\testxml.xml");
    386     string l_strFileName2("F:\Desktop\20140411\测试\testxml2.xml");
    387     tptree pt;
    388     bool f = LoadXML(pt, l_strFileName1);
    389 
    390     //测试IsExistChildNode函数
    391     //tstring l_strNodePath(_USERT("config.departments.department.info.person.<xmlattr>.id"));
    392     //int l_nState1 = IsExistChildNode(pt, l_strNodePath);
    393 
    394     //测试IsExistChildNode函数
    395     //tstring l_strNodePath(_USERT("config.departments.department.info.person")); //有直接子节点或者属性
    396     //int l_nState2 = IsExistChildNode(pt, l_strNodePath);
    397 
    398     //测试IsChildNodeOrAttr函数
    399     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    400     //bool l_bChildNodeOrAttribute;
    401     //int l_nChildNodeCount;
    402     //int l_nChildNodeAttributeCount;
    403     //bool f3 = IsChildNodeOrAttr(pt, l_strNodePath, l_bChildNodeOrAttribute, l_nChildNodeCount, l_nChildNodeAttributeCount);
    404 
    405     //测试IsChildNodeOrAttr函数
    406     //tstring l_strNodePath(_USERT("config.departments.department.info.person"));
    407     //bool l_bChildNodeOrAttribute;
    408     //int l_nChildNodeCount;
    409     //int l_nChildNodeAttributeCount;
    410     //bool f3 = IsChildNodeOrAttr(pt, l_strNodePath, l_bChildNodeOrAttribute, l_nChildNodeCount, l_nChildNodeAttributeCount);
    411 
    412     //测试GetChildNodes函数
    413     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    414     //bool l_bChildNodeOrAttribute;
    415     //int l_nChildNodeCount;
    416     //int l_nChildNodeAttributeCount;
    417     //bool f4 = IsChildNodeOrAttr(pt, l_strNodePath, l_bChildNodeOrAttribute, l_nChildNodeCount, l_nChildNodeAttributeCount);
    418     //bool f5;
    419     //multimap<tstring, tstring> l_mapChildNodes;
    420     //if (l_bChildNodeOrAttribute)
    421     //{
    422     //    f5 = GetChildNodes<tstring>(pt, l_strNodePath, l_mapChildNodes);
    423     //}
    424 
    425     //测试GetChildNodes函数
    426     //typ==int error
    427     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    428     //bool l_bChildNodeOrAttribute;
    429     //int l_nChildNodeCount;
    430     //int l_nChildNodeAttributeCount;
    431     //bool f4 = IsChildNodeOrAttr(pt, l_strNodePath, l_bChildNodeOrAttribute, l_nChildNodeCount, l_nChildNodeAttributeCount);
    432     //bool f5;
    433     //multimap<tstring, int> l_mapChildNodes;
    434     //if (l_bChildNodeOrAttribute)
    435     //{
    436     //    f5 = GetChildNodes<int>(pt, l_strNodePath, l_mapChildNodes);
    437     //}
    438 
    439     //测试GetChildNodes函数
    440     //tstring l_strNodePath(_USERT("config.departments.department"));
    441     //bool l_bChildNodeOrAttribute;
    442     //int l_nChildNodeCount;
    443     //int l_nChildNodeAttributeCount;
    444     //bool f4 = IsChildNodeOrAttr(pt, l_strNodePath, l_bChildNodeOrAttribute, l_nChildNodeCount, l_nChildNodeAttributeCount);
    445     //bool f5;
    446     //multimap<tstring, tstring> l_mapChildNodes;
    447     //if (l_bChildNodeOrAttribute)
    448     //{
    449     //    f5 = GetChildNodes<tstring>(pt, l_strNodePath, l_mapChildNodes);
    450     //}
    451 
    452     //测试GetCurrentNodeAttrs函数
    453     //tstring l_strNodePath(_USERT("config.departments.department.info.person"));
    454     //multimap<tstring, tstring> l_mapChildNodes;
    455     //bool f5 = GetChildNodes<tstring>(pt, l_strNodePath, l_mapChildNodes);
    456 
    457     //测试GetCurrentNodeAttrs函数
    458     //tstring l_strNodePath(_USERT("config.departments.department.info.person"));
    459     //bool l_bChildNodeOrAttribute;
    460     //int l_nChildNodeCount;
    461     //int l_nChildNodeAttributeCount;
    462     //bool f4 = IsChildNodeOrAttr(pt, l_strNodePath, l_bChildNodeOrAttribute, l_nChildNodeCount, l_nChildNodeAttributeCount);
    463     //bool f5;
    464     //map<tstring, tstring> l_mapChildNodeAttrs;
    465     //if (!l_bChildNodeOrAttribute)
    466     //{
    467     //    f5 = GetCurrentNodeAttrs<tstring>(pt, l_strNodePath, l_mapChildNodeAttrs);
    468     //}
    469 
    470     //测试GetChildNodesAttrs函数
    471     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    472     //bool f5;
    473     ////map<tstring, tstring> l_mapChildNodeAttrs;
    474     //multimap<tstring, map<tstring, tstring>> l_mmapChildNodesAttrs;
    475     //f5 = GetChildNodesAttrs<tstring>(pt, l_strNodePath, l_mmapChildNodesAttrs);
    476 
    477     //测试SetCurrentNodeValue函数
    478     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    479     //tptree::iterator iter= pt.get_child(l_strNodePath).begin();
    480     //tstring l_strNodeValue = _USERT("testvalue");
    481     //bool f6 = SetCurrentNodeValue(iter, l_strNodeValue);
    482 
    483     //测试SetCurrentNodeAttrValue函数
    484     //tstring l_strNodePath(_USERT("config.departments.department.info.person.<xmlattr>"));
    485     //tptree::iterator iter= pt.get_child(l_strNodePath).begin();
    486     //tstring l_strNodeValue = _USERT("testvalue");
    487     //bool f6 = SetCurrentNodeAttrValue(iter, l_strNodeValue);
    488 
    489     //测试DelCurrentNode函数
    490     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    491     //tptree &childpt = pt.get_child(l_strNodePath);
    492     //tptree::iterator iter = childpt.begin();
    493     //bool f6 = DelCurrentNode(childpt, ++iter);
    494     
    495     //测试DelCurrentNode函数
    496     //tstring l_strNodePath(_USERT("config.departments.department.info.person.<xmlattr>"));
    497     //tptree &childpt = pt.get_child(l_strNodePath);
    498     //tptree::iterator iter = childpt.begin();
    499     //bool f6 = DelCurrentNode(childpt, ++iter);
    500 
    501     //测试DelCurrentNodes函数
    502     //tstring l_strNodePath(_USERT("config.departments.department.info"));
    503     //tptree &childpt = pt.get_child(l_strNodePath);
    504     //tptree::key_type kt = childpt.begin()->first;
    505     //tptree::size_type st6 = DelCurrentNodes(childpt, kt);
    506 
    507     //测试DelCurrentNodes函数
    508     //tstring l_strNodePath(_USERT("config.departments.department.info.person.<xmlattr>"));
    509     //tptree &childpt = pt.get_child(l_strNodePath);
    510     //tptree::key_type kt = childpt.begin()->first;
    511     //tptree::size_type st6 = DelCurrentNodes(childpt, kt);
    512 
    513     //bool f2 = SaveXML(pt, l_strFileName2);
    514 
    515     cout << endl;
    516 }

     testxml.xml测试文件:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <config>
     3   <mainformsize height="600" width="330" top="50" left="500"/>
     4   <applicationtitle>GoCom统一通讯应用平台</applicationtitle>
     5   <loginmark>
     6       <fontsize>14</fontsize>
     7       <fontcolor>$0000ff</fontcolor>
     8       <lantern>true</lantern>
     9       <clientversion>5.3.5.17</clientversion>
    10       <serverip>imbs1.smartdot.com.cn</serverip>
    11   </loginmark>
    12   <departments>
    13       <department>
    14           <name>donghe</name>
    15           <level>2</level>
    16           <personcount>3</personcount>
    17           <info>
    18               <person id="1_1_1" name="王慧敏"/>
    19               <person id="1_1_2" name="刘东升"/>
    20               <person id="1_1_3" name="张智卓"/>
    21           </info>
    22       </department>
    23       <department>
    24           <name>boyun</name>
    25           <level>2</level>
    26           <personcount>3</personcount>
    27           <info>
    28               <person id="1_2_1" name="朗朗"/>
    29               <person id="1_2_2" name="隋国龙"/>
    30           </info>
    31       </department>
    32   </departments>
    33 </config>

    注:代码可以正常运行在VS2010环境下,先下载安装boost库并添加到项目中,代码才能正常运行。

    煮酒论英雄
  • 相关阅读:
    关于applet
    Hello.java
    filter用户授权的例子
    logfilter
    Java EE课程设计——企业人力资源管理系统
    条件查询、SQL、JPQL、HQL比较
    web service和ejb的区别
    RPC
    hashcode()和equals()的区别
    关于JSON
  • 原文地址:https://www.cnblogs.com/superstargg/p/3704755.html
Copyright © 2011-2022 走看看