zoukankan      html  css  js  c++  java
  • [xml解析]rapidxml读取文件

    因为项目需要读取xml配置文件,在原来调查一番后,项目组使用了tinyxml.

    tinyxml确实简单,非常清楚的就把读取方案写出来了。但是,由于后期xml文件越来越大(2.5M,大概1w多行数据),结果导致运行速度越来越低(17s)。

    于是,不得不开始寻找改善方案。

    在网上调查一番后,普遍认为xml读取有以下的几种方式:

    RapidXml、pugixml 0.3pugxmlTinyXml

    并且清楚的给出了各个之间的性能对比。

    Platform
    Compiler
    strlen()RapidXmlpugixml 0.3pugxmlTinyXml
    Pentium 4
    MSVC 8.0
    2.5
    5.4
    7.0
    61.7
    298.8
    Pentium 4
    gcc 4.1.1
    0.8
    6.1
    9.5
    67.0
    413.2
    Core 2
    MSVC 8.0
    1.0
    4.5
    5.0
    24.6
    154.8
    Core 2
    gcc 4.1.1
    0.6
    4.6
    5.4
    28.3
    229.3
    Athlon XP
    MSVC 8.0
    3.1
    7.7
    8.0
    25.5
    182.6
    Athlon XP
    gcc 4.1.1
    0.9
    8.2
    9.2
    33.7
    265.2
    Pentium 3
    MSVC 8.0
    2.0
    6.3
    7.0
    30.9
    211.9
    Pentium 3
    gcc 4.1.1
    1.0
    6.7
    8.9
    35.3
    316.0

    抱着试一试的态度,我采用了rapidxml来进行改善,结果运行速度减少到了1.6S!

    下面是rapidxml的一些使用注意事项,总结一下,帮助大家少走弯路。

    1.大家网上百度的时候,肯定都会存在这样的代码:

    1     file<> fdoc("config.xml");  
    2     std::cout<<fdoc.data()<<std::endl;   
    3     xml_document<>   doc;      
    4     doc.parse<parse_full>(fdoc.data());   

    代码本身是没有错的,但是导入工程后,就会在file<> fdoc抛出异常。

    调查许久后发现:file<> fdoc后面必须是绝对路径,所以我们读取的时候不必要像上面那么书写,可以这样:

    1     using namespace rapidxml;
    2     std::string strXml = m_strXmlPath;  // m_strXmlPath是获取xml路径的方法,可以自己去实现
    3     strXml.append("\CA_Basic.xml");
    4     file<> fdoc(strXml.c_str());
    5     xml_document<> doc;
    6     doc.parse<0>(fdoc.data());

    2.网上的xml的格式都是很整齐的,比如:

     1 <config>
     2     <color>
     3         <red>0.1</red>
     4         <green>0.1</green>
     5         <blue>0.1</blue>
     6         <alpha>1.0</alpha>
     7     </color>
     8     <size>
     9         <x>640</x>
    10         <y>480</y>
    11         <w>0</w>
    12         <h>0</h>
    13     </size>
    14     <mode fullscreen="false">screen mode</mode>
    15 </config>

    这样读取起来确实和简单,按照一下的方案就行了。

    1     //! 获取根节点  
    2     xml_node<>* root = doc.first_node();  
    3   
    4     //! 获取根节点第一个节点  
    5     xml_node<>* node1 = root->first_node();  
    6     xml_node<>* node11 = node1->first_node();  
    7     ......

    可是实际运用的时候不会这么简单的,比如我们有以下的xml:

     1 <ca_table>
     2   <ce_port no="0">
     3     <ca item_id ="10004000" curr_ec="1" next_ec="2">
     4      <firm no ="0" vv ="10" ll ="40" pp ="0000"> </firm>
     5      <firm no ="1" vv ="11" ll ="40" pp ="0000"> </firm>
     6      <board_hard pn ="CA07111-C631" sn ="PP09280285" rev ="40" other =""> </board_hard>
     7      <port port_no ="0" item_id ="11004000" rate ="0" node_name="500000E0D1000100" wwn="500000E0D1000100" MacAddress="B0ACFAA3A000" lu_reset_scope="01" reserveCancel="00"> 
     8      </port>
     9    </ca>
    10   </ce_port>
    11 </ca_table>

    这个时候就比较麻烦了,我们可以这样去读取:

     1 using namespace rapidxml;
     2 std::string strXml = m_strXmlPath;
     3 strXml.append("\CA_Basic.xml");
     4 file<> fdoc(strXml.c_str());
     5 xml_document<> doc;
     6 doc.parse<0>(fdoc.data());
     7 
     8 xml_node<>* root = doc.first_node();                         // 获取根节点<ca_table>
     9 xml_node<>* pCePortNodeBasic = root->first_node("ce_port");  // 获取节点<ce_port>
    10 if (!pCePortNodeBasic) {
    11     return;
    12 }
    13 xml_node<>* pCaBasic = pCePortNodeBasic->first_node("ca");   // 获取节点<ca>
    14 xml_attribute<>* p = pCaBasic ->first_attribute(“item_id”);  // 获取节点<ca>中的itemid
    15 unsigned long long value = strtol(p->value(), NULL, 16);     // p->value()获取的是字符,需要将其转换为数值类型
    
    

    3.并列的xml怎么处理?

    跟tinyxml一样,rapidxml也自己封装了搜寻下一个并列的xml的函数next_sibling(),直接调用即可。

    4.命名空间rapidxml

    在使用rapidxml的时候,尽可能的在调用rapidxml的地方再使用rapidxml命名空间,最好不要放到全局,以免引起混淆和带来性能问题

  • 相关阅读:
    django 参考
    数据库答案
    django -- form表单
    django ajax
    Django----中间件详解
    ORM中自定义一个char类型字段
    北理工《网站设计与开发实践》在线作业 附答案
    正则表达式 ?P<name>
    Django模板语言相关内容
    【CSS】 布局之多列等高
  • 原文地址:https://www.cnblogs.com/hustcser/p/4205838.html
Copyright © 2011-2022 走看看