[xml解析]rapidxml读取文件
因为项目需要读取xml配置文件,在原来调查一番后,项目组使用了tinyxml.
tinyxml确实简单,非常清楚的就把读取方案写出来了。但是,由于后期xml文件越来越大(2.5M,大概1w多行数据),结果导致运行速度越来越低(17s)。
于是,不得不开始寻找改善方案。
在网上调查一番后,普遍认为xml读取有以下的几种方式:
RapidXml、pugixml 0.3、pugxml、TinyXml
并且清楚的给出了各个之间的性能对比。
| Platform | Compiler | strlen() | RapidXml | pugixml 0.3 | pugxml | TinyXml |
|---|---|---|---|---|---|---|
| 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.大家网上百度的时候,肯定都会存在这样的代码:
file<> fdoc("config.xml");
std::cout<<fdoc.data()<<std::endl;
xml_document<> doc;
doc.parse<parse_full>(fdoc.data());
代码本身是没有错的,但是导入工程后,就会在file<> fdoc抛出异常。
调查许久后发现:file<> fdoc后面必须是绝对路径,所以我们读取的时候不必要像上面那么书写,可以这样:
using namespace rapidxml;
std::string strXml = m_strXmlPath; // m_strXmlPath是获取xml路径的方法,可以自己去实现
strXml.append("\\CA_Basic.xml");
file<> fdoc(strXml.c_str());
xml_document<> doc;
doc.parse<>(fdoc.data());
2.网上的xml的格式都是很整齐的,比如:
<config>
<color>
<red>0.1</red>
<green>0.1</green>
<blue>0.1</blue>
<alpha>1.0</alpha>
</color>
<size>
<x>640</x>
<y>480</y>
<w>0</w>
<h>0</h>
</size>
<mode fullscreen="false">screen mode</mode>
</config>
这样读取起来确实和简单,按照一下的方案就行了。
//! 获取根节点
xml_node<>* root = doc.first_node(); //! 获取根节点第一个节点
xml_node<>* node1 = root->first_node();
xml_node<>* node11 = node1->first_node();
......
可是实际运用的时候不会这么简单的,比如我们有以下的xml:
<ca_table>
<ce_port no="0">
<ca item_id ="10004000" curr_ec="1" next_ec="2">
<firm no ="0" vv ="10" ll ="40" pp ="0000"> </firm>
<firm no ="1" vv ="11" ll ="40" pp ="0000"> </firm>
<board_hard pn ="CA07111-C631" sn ="PP09280285" rev ="40" other =""> </board_hard>
<port port_no ="0" item_id ="11004000" rate ="0" node_name="500000E0D1000100" wwn="500000E0D1000100" MacAddress="B0ACFAA3A000" lu_reset_scope="01" reserveCancel="00">
</port>
</ca>
</ce_port>
</ca_table>
这个时候就比较麻烦了,我们可以这样去读取:
using namespace rapidxml;
std::string strXml = m_strXmlPath;
strXml.append("\\CA_Basic.xml");
file<> fdoc(strXml.c_str());
xml_document<> doc;
doc.parse<>(fdoc.data()); xml_node<>* root = doc.first_node(); // 获取根节点<ca_table>
xml_node<>* pCePortNodeBasic = root->first_node("ce_port"); // 获取节点<ce_port>
if (!pCePortNodeBasic) {
return;
}
xml_node<>* pCaBasic = pCePortNodeBasic->first_node("ca"); // 获取节点<ca>
xml_attribute<>* p = pCaBasic ->first_attribute(“item_id”); // 获取节点<ca>中的itemid
unsigned long long value = strtol(p->value(), NULL, ); // p->value()获取的是字符,需要将其转换为数值类型
3.并列的xml怎么处理?
跟tinyxml一样,rapidxml也自己封装了搜寻下一个并列的xml的函数next_sibling(),直接调用即可。
4.命名空间rapidxml
在使用rapidxml的时候,尽可能的在调用rapidxml的地方再使用rapidxml命名空间,最好不要放到全局,以免引起混淆和带来性能问题
[xml解析]rapidxml读取文件的更多相关文章
- TinyXML:一个优秀的C++ XML解析器[转]
TinyXML:一个优秀的C++ XML解析器 读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似 ...
- XML解析【介绍、DOM、SAX详细说明、jaxp、dom4j、XPATH】
什么是XML解析 前面XML章节已经说了,XML被设计为"什么都不做",XML只用于组织.存储数据,除此之外的数据生成.读取.传送等等的操作都与XML本身无关! XML解析就是读取 ...
- XML解析之sax解析案例(一)读取contact.xml文件,完整输出文档内容
一.新建Demo2类: import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXPar ...
- XXE任意文件读取(当xml解析内容有输出时)
利用XXE漏洞读取文件 参考:https://www.jianshu.com/p/4fc721398e97 首先找到登录源码如下: 由题目可以利用XXE漏洞读取文件 先登录用Burp Suite抓包: ...
- XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax
本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...
- Android之ProgressBar读取文件进度解析
ProgressBar进度条, 分为旋转进度条和水平进度条,进度条的样式根据需要自定义,之前一直不明白进度条如何在实际项目中使用,网上演示进度条的案例大多都是通过Button点 击增加.减少进度值,使 ...
- Unity的Json解析<一>--读取Json文件
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50373558 作者:car ...
- android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入SD卡中的xml文件
前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...
- android XMl 解析神奇xstream 四: 将复杂的xml文件解析为对象
前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...
随机推荐
- Android学习系列(1)--为App签名(为apk签名)
写博客是一种快乐,前提是你有所写,与人分享,是另一种快乐,前提是你有舞台展示,博客园就是这样的舞台.这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 1.签 ...
- unix network programming(3rd)Vol.1 [第1章]《读书笔记系列》
文章最开头介绍了 获取时间的C/S 模型的代码, 还用了实现了IPV6的版本 unix 介绍了errno值,以及在多进程/多线程中的问题 多线程中不用全局errno,而是用返回值 处理error 详细 ...
- Go语言项目的错误和异常管理 via 达达
Go语言项目的错误和异常管理 最近连续遇到朋友问我项目里错误和异常管理的事情,之前也多次跟团队强调过错误和异常管理的一些概念,所以趁今天有动力就赶紧写一篇Go语言项目错误和异常管理的经验分享. 首先我 ...
- MySQL查询大小写是否敏感问题分析
mysql数据库在做查询时候,有时候是英文字母大小写敏感的,有时候又不是的,主要是由mysql的字符校验规则的设置决定的,通常默认是不支持的大小写字母敏感的. 1. 什么是字符集和校验规则? 字符集 ...
- BNU 51275 道路修建 Large 并查集
分析(引入Q神题解 %%%Q) 如果使用可持久化并查集,二分答案判定连通性,复杂度是O(mlog3n),不能在时限内出解.考虑到并查集实际上是一棵树,可以尝试在边上维护一些信息,假设t时刻加了一条边 ...
- java deleteOnExit函数用法
Java的File类中有两个delete方法:delete和deleteOnExit delete无需解释,为直接删除,deleteOnExit文档解释为:在虚拟机终止时,请求删除此抽象路径名表示的文 ...
- sql-定义变量
declare @subject nvarchar(50) set @subject=(select Subject from dbo.Scores where ID=1) --select @sub ...
- 关于使用digitalocean的vps
先说说测试速度 平均在延迟125ms,机房选择新加坡 还有其他机房,比如伦敦,西海岸,阿姆斯特丹,基本全球覆盖. 以前用linode,virpus. linode以前有$5的套餐,现在最低都在10刀了 ...
- 在iptables中添加vnc访问规则
iptables -I INPUT -p tcp --dport 5800|5900|5801|5901 -j ACCEPT service iptales save
- 矩阵取数游戏 NOIP 2007
2016-05-31 17:26:45 题目链接: NOIP 2007 矩阵取数游戏(Codevs) 题目大意: 给定一个矩阵,每次在每一行的行首或者行尾取一个数乘上2^次数,求取完最多获得的分数 解 ...