查看完整版本: [-- dom  sax  stream 的区别 --]

QTCN开发网 -> Qt基础编程 -> dom  sax  stream 的区别 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

ppdayz 2011-03-31 11:08

dom  sax  stream 的区别

  刚刚在看QT XML的例子,里面有3个关于xml的例子,都是关于书签的,分别是dombookmarks, saxdombookmarks和 streamdombookmarks ,功能都差不多,开始搞不明白有什么区别,去查了下,搞明白了,希望给大家节约点时间,不用去查了,就现分享下
原文地址:http://hi.baidu.com/shaobz/blog/item/5f5886880a2ab4749f2fb401.html



传统的处理XML的API有DOM和SAX两种,DOM速度慢,占用内存极大。SAX虽然比DOM快,但速度任不理想。现在,一种新的基于流的Stream API for XML(简称 StAX)极大地提高了XML的处理速度,并且已经称为JSR 173标准(http://www.jcp.org/en/jsr/detail?id=173)。目前,StAX最好的开源实现是Woodstox(http://woodstox.codehaus.org/),它完整地支持StAX API。Resin3.1也内置了StAX的实现,但是并没有支持所以的StAX API。XFire在ClassPath上如果找到了StAX API的定义,就会试图定位一个StAX的实现。

简说XML的解析方式(DOM,SAX,StAX)

一般来说,解析XML文件存在着两种方式,一种是event-based API,比如说象SAX,XNI. 第二种是tree-based API,比如说DOM,JDOM,DOM4j等等.
一般来说,读取配置文件时,我们一般比较喜欢应用tree-based API这种方式,就是把xml文件读入,变成DOM形式的一棵树,然后进行查找,获取自己说想要的东西.
   但是,这种方式有个缺点,那就是如果你这个XML文件很大的话,你需要占用很大的内存.
   所以对于很大的一个xml文件,又不需要进行随机查找的时候,比较适合采用event-based API,那就是说他解析xml文件,如果是START_ELEMENT,
   那么他就调用startElement()的回调方法..他遍历过了就过了,不能再回去.
   在event-based API中又存在两种方式: 一个是PUSH的方式,就比如说是SAX. 另外一种是PULL的方式,比如StAX.
   怎么来理解PUSH和PULL的区别呢. 先假设有这么三个角色: application, xmlFile, xmlParser. 那么,如果我们采用PUSH的方式,步骤为:
1. 创建一个xmlParser.
2. 把我们的application处理xml的注册到xmlParser.
3. xmlParser遍历xmlFile,然后来调用application.
    这里面,用的是Observer的模式,就是接收到event的时候,去调用event的callback函数, 这里面有个很不好的地方就是,你application反而是被Parser控制了.
    于是,就出现了PULL方式的解析.
1. 创建一个xmlParser
2. xmlParser打开一个xmlFile
3. application调用这个xmlParser, 来获取xmlParser打开xmlFile所得到的一系列event.
这里,用到了Iterator的模式. 最主要的一点是: 这个时候application控制了xmlParser.
StAX有两种API,一种是cursor-based,一种是iterator-based. 这两种详细的比较参考: http://java.sun.com/webservices/docs/1.6/tutorial/doc/SJSXP3.html#wp102139
这里,SAX和StAX的另外一点区别是: SAX只能读xml文件. StAX不但能读xml文件,而且还能写xml文件.





SAX (Simple API for XML) DOM (Document Object Model) 是当前两个主要的XML API,几乎所有商用的xml 解析器都同时实现了这两个接口。因此如果你的程序使用了SAX或者DOM APIs,那么你的程序对xml解析器是透明。

1. DOM以一个分层的对象模型来映射xml文档。而SAX将文档中的元素转化为对象来处理。
2. DOM将文档载入到内存中处理,而SAX则相反,它可以检测一个即将到来的XML流,由此并不需要所有的XML代码同时载入到内存中。


SAX 处理是如何工作的
     SAX
在读取 XML 流的同时处理它们,这很像以前的自动收报机纸带(ticker tape)。请考虑下面的 XML 代码片断:
<?xml version="1.0"?>
<samples>
    <server>UNIX</server>
    <monitor>color</monitor>
</samples>
    
分析这个代码片断的 SAX 处理器一般情况下将产生以下事件:
Start document
Start element (samples)
Characters (white space)
Start element (server)
Characters (UNIX)
End element (server)
Characters (white space)
Start element (monitor)
Characters (color)
End element (monitor)
Characters (white space)
End element (samples)
SAX API
允许开发人员捕捉这些事件并对它们作出反应。
     SAX
处理涉及以下步骤:
      1.
创建一个事件处理程序。
      2.
创建 SAX 解析器。
      3.
向解析器分配事件处理程序。
      4.
解析文档,同时向事件处理程序发送每个事件。
    
基于事件的处理的优点和缺点
    
这种处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX 还比它的替代者 DOM 快许多。
另一方面,由于应用程序没有以任何方式存储数据,使用 SAX 来更改数据或在数据流中往后移是不可能的。
     DOM
和基于树的处理
     DOM
是处理 XML 数据的传统方法。使用 DOM 时,数据以树状结构的形式被加载到内存中。
    
例如,在“SAX 处理是如何工作的”中用作例子的相同文档在 DOM 中将表示为节点,DOM 使用父子关系。
    
基于树的处理的优点和缺点
     DOM
以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。
另一方面,在内存中构造这样的树涉及大量的开销。大型文件完全占用系统内存容量的情况并不鲜见。此外,创建一棵 DOM 树可能是一个缓慢的过程。
    
如何在 SAX DOM 之间选择
    
选择 DOM 还是选择 SAX,这取决于下面几个因素:
1.
应用程序的目的:如果打算对数据作出更改并将它输出为 XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用 SAX 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。
2.
数据容量: 对于大型文件,SAX 是更好的选择。
数据将如何使用:如果只有数据中的少量部分会被使用,那么使用 SAX 来将该部分数据提取到应用程序中可能更好。 另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么 SAX 也许不是恰当的选择。
3.
对速度的需要: SAX 实现通常要比 DOM 实现更快。
SAX
DOM 不是相互排斥的,记住这点很重要。您可以使用 DOM 来创建 SAX 事件流,也可以使用 SAX 来创建 DOM 树。事实上,用于创建 DOM 树的大多数解析器实际上都使用 SAX 来完成这个任务!

XChinux 2020-09-02 08:37
注意,http://woodstox.codehaus.org/
这个网站已失效,下面是一些说明:
https://projectmanagernews.com/general/most-important-projects-codehaus/


查看完整版本: [-- dom  sax  stream 的区别 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled