梦想的天堂

常用链接

统计

最新评论

XML字符串解析介绍

        前些天在做一个小项目,需要实现从字符串到XML文件的逆向转换过程。该字符串由XML文件所得。由于使用环境对解析时间和内存使用量有严格的要求,因此必须确保解析速度和所占用内存。
      下面简单叙述一下我的实现过程。最开始采用的方法是每次从文件字符串里面读入一个节点的值,具体读取过程有xml文件各个节点属性决定。再利用一个stack对xml文件节点进行管理。大致思路是每读入一个字符串,先判断其类型,如果是Element或者text, comment, cdata类型则入栈,若为EndElement则出栈,这样就可以顺利建立起各个父子节点之间的关系。
     采用这样的方法是思路比较的明确,实现起来比较的简单,缺点是解析速度太慢了,解析一个2M左右的XML文件要10多分钟,而且所费时间与文件的大小成几何级别增长,根本不可能接受。在采用这种方法过程中,也出现了一个小插曲。就是在解析比较大的xml文件时,当解析的xml节点超过1500个时,就会导致内存分配错误,堆栈溢出,开始是百思不得其解,后来才知道是由于我在解析字符串过程中,采用了递归的方法,因此内存消耗很厉害,特别是我开始传入一个const字符串时,一个小小的几百K(以200k为例)的文件就可能导致内存一下子消耗几百M,因为每次只读入一个节点字符串,这样最终大小可以达到200K+19.96k+....+0 ~=200*(200-1)k/2~ = 200M.因此导致编译器堆栈溢出,解决方法有几种,一是将堆栈设置大些,另外就是改递归为循环。我采用了后者。
     在进行字符串解析时,我大量采用了STL的字符串find,find_first_of(),substr等

函数,但是这通常只在搜索小字符串时速度较快,在长达几M的字符串时,由于大块的内存操作,程序运行慢如蜗牛。而且我在前面的实现方法中,每次是提取一个节点,然后再进行解析,这样在读取和解析过程中,会导致许多重复的步骤,严重影响工作效率。 于是我就采用一个了for循环对读入的一个个字节进行处理,这样速度得到显著的提高。但是程序在解析大字符串时还是运行很慢,我开始 意识到是长字符串的问题,因此得想方法分段解析才行。于是决定每次从字符串里面提取一定的字符处理。在解析长达几M的字符串时,我先后试验了每次提取64bit,128bit,256bit,512bit, 1k, 2k, 4k等不同长度的字符串,发现在处理大字符串时,4K的效果最好。在解析一个8M左右的xml字符串时,速度可以达到30S,但是内存消耗有点厉害了,达100M。因此也很难满足要求。
     最后还是采用了一种比较折中的方法,就是在初次解析时,只解析根节点以及其下一层子节点,在保存过程中再分段解析,主要可以极大的减少内存消耗,8M左右的文件可以降低到20M左右内存。速度也有所提高,最终耗时3s左右。

posted on 2007-06-17 23:02 IT民工 阅读(2175) 评论(2)  编辑 收藏 引用

评论

# re: XML字符串解析介绍 2007-08-27 18:17 c++ FANS

你好,看了你的XML解析,想和你交流交流,可否?
QQ:4427598
谢谢!  回复  更多评论   

# re: XML字符串解析介绍[未登录] 2014-08-25 14:25 12

12  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理