XML解析DOM和SAX模型对比分析

 

开发XML应用程序常用的几种模型

        您可以使用根据以下这些模型创建的API 来分析和操纵 XML 结构,这些模型可以是基于对象(基于树)的,如文档对象模型(Document Object Model,DOM);也可以是基于事件(基于流、推模型)的,如 Simple API for XML(SAX)。
        JDOM试图用 DOM 和 SAX 20% 的功能来满足 80% 的用户需求,它使用 SAX 和 DOM 解析器,作为一组相
对较小的 Java 类被实现。而Java API for XML Parsing(JAXP)和MSXML提供了使用 DOM、SAX等处理XML文档的通用接口。现在,.NET框架也提供了分别基于DOM的XmlDocment类以及基于流(拉模型)的XmlReader类等。

 

DOM、SAX及其比较与选择

        用于读取和操作 XML 文件的标准是文档对象模型DOM。 DOM为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后您的代码就可以使用 DOM 接口来操作这个树结构。您可以遍历树以了解原始文档包含了什么,您可以删除树的几个部分,还可以重新排列树和添加新的分支,等等。遗憾的是,因为DOM 方法涉及读取整个文件并将该文件存储在一个树结构中,而这样可能是低效的、缓慢的,并且很消耗资源:
            DOM 构建整个文档驻留内存的树。如果文档很大,就会要求有极大的内存。
            DOM 创建表示原始文档中每个东西的对象,包括元素、文本、属性和空格。如果您只需关注原始文档的
一小部分,那么创建那些永远不被使用的对象是极其浪费的。
            DOM 解析器必须在您的代码取得控制权之前读取整个文档。对于非常大的文档,这会引起显著的延迟。
        这些仅仅是由文档对象模型的设计引起的问题;撇开这些问题,DOM API 是解析 XML 文档非常有用的
方法。

一种替代技术就是SAX。相比于文档对象模型DOM,SAX 是读取和操作 XML 数据的更快速、更轻量的方法。SAX 允许您在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。它不涉及 DOM 所必需的开销和概念跳跃。


        SAX API是一个基于事件的 API,适用于处理数据流,即随着数据的流动而依次处理数据。SAX API 在其解析您的文档时发生一定事件的时候会通知您。在您对其响应时,您不作保存的数据将会被抛弃。

        在使用DOM的情况下,解析器做了绝大多数事情, 读入XML文档, 在这基础之上创建对象模型,然后给你
一个对这个对象的引用(一个 Document对象),因而你可以操作使用它。SAX没有期待解析器去做这么多工作,所有SAX 要求的是解析器应该读入XML文档,同时根据所遇到的XML文档的标签向一个事件处理程序发出一系列事件,比如元素开始和元素结束,而事件处理器则处理该信息:你要自己写一个XML文档处理器类(XML document handler class)来处理这些事件,这意味着使所有标签事件有意义还有用你自己的对象模型创建对象。所以你要完成:
            控制所有XML文档信息的自定义对象模型。
            一个监听SAX事件(事件由SAX解析器读取你的XML文档时产生)的文档处理器,还有解释这些事件创建你自定义对象模型中的对象。
        如果你的对象模型简单的话那么SAX在运行时会非常快。在这种情况下,它会比DOM快,因为它忽略了为
你的信息创建一个树形对象模型的过程。从另一方面来说,你必须写一个SAX 文档处理器来解释所有的SAX事件(这会是一件很繁重的工作)。基于事件的API 消除了在内存中构造树的需要,却不允许开发人员实际更改原始文档中的数据。所以原始的文档仍然保留完好无损;但是 SAX 提供了操作数据的手段,而后数据可以引入另一个进程或文档。

        要使用 XML 文档做任何事情,你都必须读取其中的信息。做这个工作的应用程序称为解析器。它设计用于分析文档(这里是指 XML 文件),以及做一些特定于该信息的事情。在诸如 SAX 这样基于事件的 API 中,解析器将向某种监听器发送事件。在诸如 DOM 这样基于树的 API 中,解析器将在内存中构造一颗数据树。
解析器的两种类型分别是:非验证 和 验证。
        非验证解析器是适用于格式良好(well-formed)文档的解析器。 它读取每个信息单元,并将其添加到文档 ―― 或者在 SAX 应用程序的情况下处理事件,而不管实际的结构和内容如何。 另一方面,验证解析器根据已定义的语法检查 XML 文档的内容和结构。 有时,这个语法是文档类型定义(Document Type Definition,DTD)的形式,但是它更可能在 XML Schema 文档中定义。在任一种情况下,解析器都会检查文档,以确保每个元素和属性都已定义,并且包含正确类型的内容。例如,您可以指定每个 order(订单) 都有一个status(状态)。 如果在没有语法定义的情况下尝试创建文档,验证解析器将会提示错误。
        已经由验证解析器检验过的文档被认为是有效的文档。

 

SAX 的几个特征解决了 DOM 的问题:

        SAX 解析器向您的代码发送事件。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,它会告诉您。您可以决定什么事件对您重要,而且可以决定要创建什么类型的数据结构以保存来自这些事件的数据。如果您没有显式地保存来自某个事件的数据,它就被丢弃。
        SAX 解析器根本不创建任何对象,它只是将事件传递给您的应用程序。如果希望基于那些事件创建对象
,这将由您来完成。
        SAX 解析器在解析开始的时候就开始发送事件。当解析器发现文档开始、元素开始和文本等时,代码会
收到一个事件。您的应用程序可以立即开始生成结果;您不必一直等到整个文档被解析完毕。更妙的是,如果您只查找文档中某些内容,代码一旦找到所要找的东西就可以抛出一个异常。该异常会停止 SAX 解析器,然后代码用它找到的数据做它需要做的任何事。


公平而言,SAX 解析器也有些问题引人关注:

        DOM 所提供的丰富的标准功能在 SAX 中是没有的。
        SAX 事件是无状态的。当 SAX 解析器在 XML 文档中发现文本时,它就向您的代码发送一个事件。该事
件仅仅给您发现的文本;它不告诉您什么元素包含那个文本。如果您想知道这一点,则必须自己编写状态管理代码。
        SAX 事件不是持久的。如果应用程序需要一个数据结构来对 XML 文档建模,则必须自己编写那样的代
码。如果您需要从 SAX 事件访问数据,并且没有把那个数据存储在代码中,那么您不得不再次解析该文档。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值