昨天,客户报了个Bug过来:html5应用在ipad下卡住不动了。按照他发过来的地址,初步诊断是xml解析的性能问题。应用初始化时要加载几个xml配置文件,客户给的地址中,一个配置文件有800多K(文件A),另一个配置文件有400多K(文件B)。我修改了程序,在PC机上用Safari模拟ipad登录,解析文件A花了30多秒。一般来说,ipad2的性能是我的PC机的1/5,在ipad上解析这个xml文件至少要花150秒。这是不能接受的。同样的程序,在ie下测试,仅仅耗时160ms!我用的是haXe的xml库,在ie9和在safari上竟然有这么大的性能差距。

又找了几个xml库,不是无法运行,就是执行失败。实在没有办法,只好用domparser来解析,当html文件处理。使用domparser可以极大的提高性能,还是以文件A为例子,在PC的safari上解析耗时降为1秒左右,这个时间是可以承受的。然而,使用domparser存在一个问题,就是无法提取出CData数据。http://stackoverflow.com/questions/5227592/extract-cdata-from-rss-xml-using-javascript 给出了一个解决方案:将CData数据用标签围住,这是一种思路。于是,修改程序,将<![CDATA[替换为<cdata>,将]]>替换成</cdata>。

提取cdata标签的数据,当作XML文件的CData数据/。问题似乎解决了,经过多次测试,又发现了新的问题:

CData中有很多字符没有转义。在CData中倒是无害,但在<cdata></cdata>中就变成有害了。这里又要表扬下ie9:ie9在这种情况下能够正确解析,Safari不能!

既然问题出现在CData,那么我们就对CData数据进行预处理:
(1),找到每个CData数据,为它编号;
(2),对每个CData片段,用它的编号进行替换,这样就屏蔽了敏感字符;
(3),将替换后的文本,用domparser解析。

这样一来,当使用这个Dom时,碰到CData编号,再将它替换为对应的CData数据即可。因为文件A在ipad上无法解析成功,这里只对文件B的解析进行了都比。之前解析文件B耗时是13-16秒,使用新方法后,解析时间缩短为32毫秒,提高了约400倍。

====

下面的代码是用haXe写的,haXe很容易读,就不详加解释了。
CData类,存储键值对:

class CData 
{
 public var key:String;
 
 public var val:String;
 
 public function new() 
 {
 } 
}

Xml2Html类,对xml文本进行预处理,并存储CData信息:

class Xml2Html 
{
 private var map:Array<CData>;

public function new() 
 {
 }
 
 public function getCData(key:String):String
 {
  if (map == null) return null;
  
  for (i in 0 ... map.length)
  {
   var item:CData = map[i];
   if (item.key == key)
   {
    return item.val;
   }
  }
  
  return null;
 }
 
 public function prepareXmlAsHtml(txt:String):String
 {
  map = new Array<CData>();
  txt = StringTools.replace(txt, "<![CDATA[", "]]>");
  var lines:Array<String> = txt.split("]]>");
  if (lines.length == 0) return txt;
  var buff:StringBuf = new StringBuf();
  var k:Int = 0;
  for (i in 0 ... lines.length)
  {
   var val:String = lines[i];
   if (i % 2 == 0) // 正常内容
   {
    buff.add(val);
   }
   else
   {
    var key:String = Std.string(k);
    buff.add("<cdata>" + key + "</cdata>");
    var cdata:CData = new CData();
    cdata.key = key;
    cdata.val = val;
    map.push(cdata);
    k++;
   }
  }
  
  return buff.toString();
 }
}

下面是解析示例:

var ctx:Xml2Html = new Xml2Html();
  searchInfo = dom.parseFromString(ctx.prepareXmlAsHtml(data), "text/xml");
    
  var dom:HtmlDom = searchInfo;
  var pages:HtmlCollection<HtmlDom> = dom.getElementsByTagName("page");
  for (i in 0 ... pages.length)
  {
   var node:HtmlDom = pages[i];
   var pageNumVal:String = node.getAttribute("pageNumber");
   var htmlText:String = null;
   var htmlTextDoms:HtmlCollection<HtmlDom> = node.getElementsByTagName("cdata");
   if (htmlTextDoms != null && htmlTextDoms.length > 0)
   {
    htmlText = StringTools.trim(htmlTextDoms[0].childNodes[0].nodeValue);
    htmlText = ctx.getCData(htmlText);
   }
   
   for (k in 0 ... book.pages.length)
   {
    var page:Page = book.pages[k];
    if (page.id == pageNumVal)
    {
     page.content = htmlText;
    }
   }
  }

====

小结:

(1)IE9很厉害!

(2)haXe是好东东,用它写js程序很舒服。但因为是开源社区的作品,还不够成熟,需要使用者自己想办法来弥补其缺陷。

提高ipad浏览器下大尺寸xml文件解析的性能相关推荐

  1. Linux环境下——实现xml文件解析

    目录 libxml简介 libxml库安装 libxml2中的数据类型和函数 xml文档解析实例 运行结果 libxml简介 libxml是一个用于解析xml文件的库,在各个平台下都能使用,也支持多种 ...

  2. Android学习笔记之AndroidManifest.xml文件解析(摘自皮狼的博客)

    Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它 ...

  3. android基础知识13:AndroidManifest.xml文件解析【转载】

    注:本文转载于:http://blog.csdn.NET/xianming01/article/details/7526987 AndroidManifest.xml文件解析. 1.重要性 Andro ...

  4. Android开发历程_18(XML文件解析)

    前言  本文主要介绍在Android中怎样来解析XML文件.主要采用的是SAX机制,SAX全称为Simple API for XML,它既是一种接口,也是一个软件包.作为接口,SAX是事件驱动型XML ...

  5. java怎么xml文件解析_Java对Xml文件解析

    JAVA 解析 XML 通常有两种方式,DOM 和 SAX. DOM 虽然是 W3C 的标准,提供了标准的解析方式,但它的解析效率一直不尽如人意,因为使用DOM解析XML时,解析器读入整个文档并构建一 ...

  6. XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 查找校验xml文件中相同的节点属性值 java遍历文件夹解析XML

    XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 以及查找xml文件中相同的节点属性值 项目背景:这是本人实习中所碰到的项目,当时感觉很棘手, ...

  7. XML - XML学习/XML文件解析器(C++)实现

    XML - XML学习/XML文件解析器(C++)实现 XML概述 ​ XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识.它也是元标记语言,用于定义其他与特定领域有关的, ...

  8. java xml文件解析工具_Xml文件解析工具 - java

    解析Xml文件:就是把Xml文件里面的内容取出来. Xml文件解析工具:一个能解析Xml文件的类,即一个能把Xml文件里面的内容取出来的类. 先给出一个Xml文件(student_infor.xml) ...

  9. (十一)XML 文件解析以及工具实现(详解)

    XML 文件解析详解以及工具实现 文章目录 XML 文件解析详解以及工具实现 前言 解析 XML 文档 XML 解析器与 W3C XML 的层次结构 XML 解析工具化 工具化分析 本地块与静态本地块 ...

最新文章

  1. python新闻爬虫教程_python简易爬虫教程--(一)批量获取搜狐新闻
  2. Codeforces Round #717 (Div. 2) D. Cut 倍增
  3. create-react-app项目使用假数据
  4. 3 个月如何从小白到 Python 高手?清华博士带你入门带你飞!
  5. python开两个守护线程_python 守护线程
  6. 像git一样管理数据,高效的数据管理平台TensorBay来了!
  7. 安卓依然是华为手机首选,鸿蒙系统或许不用于手机
  8. tkinter Scale滑块
  9. x86汇编语言(2) 认识8086处理器
  10. 微信扫码支付模式二【无法回调】解决方案(转)
  11. 关于USB-Audio(USB麦克风)设备的录音验证
  12. 高风险IP究竟来自哪里?IP定位带你反欺诈
  13. c语言如何文件指针指向开头,fseek设置好文件指针 在C语言中fseek()的功能
  14. 怎样合并磁盘分区?看这里~
  15. 解决win10安装失败原因和方法
  16. RTC与WebRTC有什么区别?
  17. Redis系列:Redis持久化机制与Redis事务
  18. LTE: CSI 上报
  19. redis热key监控
  20. winmail中web界面破除用户限制

热门文章

  1. Mocha BSM产品亮点——事件管理
  2. 全国计算机一级计算机基础及WPS考试题型,计算机一级考试科目有哪些?Wps和ms考试的题目一样吗?...
  3. centos 7 mysql图形界面_centos7-vnstat图形界面搭建
  4. idea测试连接mysql报错08001_IDEA连接MySQL错误
  5. 第十章 某些算法的分治法解释
  6. 基于注册中心的Dubbo服务
  7. 设计模式在Netty 中的应用-策略模式源码举例
  8. Spring AOP在事务中的应用典范
  9. MapReduce案例-wordcount-JobMain代码
  10. 通过docker的方式进行RocketMQ的安装