262

我阅读了一些关于XML解析器的文章,并遇到了SAXDOM

SAX是基于事件的,而DOM是树模型——我不明白这些概念之间的区别。

据我了解,基于事件的意思是节点发生了某种事件。就像当一个人点击一个特定的节点时,它会给出所有的子节点,而不是同时加载所有的节点。但在DOM解析的情况下,它将加载所有节点并制作树模型。

我的理解正确吗?

如果我错了,请纠正我或以更简单的方式向我解释基于事件的树模型。

4

7 回答 7

326

好吧,你很接近。

在 SAX 中,在解析XML 时触发事件。当解析器解析 XML 并遇到一个开始的标签(例如<something>)时,它会触发tagStarted事件(事件的实际名称可能不同)。类似地,当解析 ( </something>) 时遇到标记的末尾时,它会触发tagEnded。使用 SAX 解析器意味着您需要处理这些事件并理解每个事件返回的数据。

在 DOM 中,解析时不会触发任何事件。解析整个 XML,并生成并返回 DOM 树(XML 中的节点)。解析后,用户可以导航树以访问先前嵌入在 XML 中的各个节点中的各种数据。

通常,DOM 更易于使用,但在开始使用之前需要解析整个 XML。

于 2011-07-26T10:41:24.790 回答
108

短短几句话...

SAX(Simple A PI for X ML):是一个基于流的处理器。您在任何时候都只有一小部分内存,并且您通过为诸如此类的事件实现回调代码来“嗅探”XML流。它几乎不使用内存,但您不能做“DOM”的东西,比如使用 xpath 或 traverse树木。tagStarted()

DOM文档对象模型:您将整个内容加载到内存中 - 这是一个巨大的内存占用。即使是中等大小的文档,您也可以使用内存。但是您可以使用 xpath 并遍历树等。

于 2011-07-26T10:49:41.737 回答
75

用更简单的话来说:

DOM

  • 树模型解析器(基于对象)(节点树)。

  • DOM 将文件加载到内存中,然后解析文件。

  • 有内存限制,因为它会在解析之前加载整个 XML 文件。

  • DOM 是可读写的(可以插入或删除节点)。

  • 如果 XML 内容很小,那么首选 DOM 解析器。

  • 向后和向前搜索可以用于搜索标签和评估标签内的信息。因此,这使导航变得容易。

  • 运行时速度较慢。

萨克斯

  • 基于事件的解析器(事件序列)。

  • SAX 在读取文件时对其进行解析,即逐个节点解析。

  • 没有内存限制,因为它不会将 XML 内容存储在内存中。

  • SAX 是只读的,即不能插入或删除节点。

  • 当内存内容很大时使用 SAX 解析器。

  • SAX 从上到下读取 XML 文件,不能向后导航。

  • 运行时更快。

于 2013-10-03T08:15:07.850 回答
38

您对基于 DOM 的模型的理解是正确的。XML 文件将作为一个整体加载,其所有内容将构建为文档所代表的树的内存表示。这可能会耗费时间和内存,具体取决于输入文件的大小。这种方法的好处是您可以轻松查询文档的任何部分,并自由操作树中的所有节点。

DOM 方法通常用于小型 XML 结构(其中小的取决于您的平台有多少马力和内存),一旦它们被加载,可能需要以不同的方式进行修改和查询。

另一方面,SAX 旨在处理几乎任何大小的 XML 输入。与 XML 框架为您找出文档的结构并为所有节点、属性等准备潜在的大量对象不同,SAX 完全将这些工作留给了您。

它的基本作用是从顶部读取输入并在某些“事件”发生时调用您提供的回调方法。一个事件可能是点击一个开始标签、标签中的一个属性、在元素内查找文本或遇到结束标签。

SAX 顽固地读取输入并以这种方式告诉您它所看到的内容。维护所需的所有状态信息由您决定。通常这意味着您将建立某种状态机。

虽然这种 XML 处理方法要繁琐得多,但它也可能非常强大。想象一下,您只想从博客提要中提取新闻文章的标题。如果您使用 DOM 读取此 XML,它会将 XML 中包含的所有文章内容、所有图像等加载到内存中,即使您甚至对它都不感兴趣。

使用 SAX,只要调用“startTag”事件方法,您就可以检查元素名称是否为(例如)“title”。如果是这样,您知道您需要添加下一个“elementText”事件为您提供的任何内容。当您收到“endTag”事件调用时,您再次检查这是否是“标题”的结束元素。之后,您只需忽略所有其他元素,直到输入结束,或者出现另一个名称为“title”的“startTag”。等等...

您可以通过这种方式读取数兆字节和数兆字节的 XML,只需提取您需要的少量数据。

当然,这种方法的不利方面是,您需要自己做更多的簿记工作,具体取决于您需要提取的数据以及 XML 结构的复杂程度。此外,您自然无法修改 XML 树的结构,因为您从来没有将它作为一个整体来掌握。

因此,一般来说,SAX 适合将您收到的潜在大量数据与特定的“查询”结合起来,但无需修改,而 DOM 更旨在为您提供更改结构和内容的充分灵活性,但代价是更高的资源需求。

于 2011-07-26T10:48:57.713 回答
17

你在比较苹果和梨。SAX 是一个解析序列化 DOM 结构的解析器。解析器有很多种,“基于事件”是指解析方式。

也许需要做一个简短的回顾:

  • 文档对象模型(DOM) 是一种抽象的数据模型,描述了分层的、基于树的文档结构;文档树由节点组成,即元素、属性和文本节点(以及其他一些节点)。节点有父节点、兄弟节点和子节点,并且可以被遍历等等,所有这些都是你在做 JavaScript 时所习惯的(顺便说一句,这与 DOM 无关)。

  • 可以使用 HTML 或 XML 等标记语言对DOM 结构进行序列化,即写入文件。因此,HTML 或 XML 文件包含抽象文档树的“写出”或“扁平化”版本。

  • 为了让计算机从文件中操作甚至显示 DOM 树,它必须反序列化或解析文件并在内存中重建抽象树。这就是解析的用武之地。

现在我们来看看解析器的本质。解析的一种方法是读取整个文档并在内存中递归地构建树结构,最后将整个结果公开给用户。(我想您可以将这些解析器称为“DOM 解析器”。)这对用户来说非常方便(我认为这就是 PHP 的 XML 解析器所做的),但它存在可伸缩性问题,并且对于大型文档来说变得非常昂贵。

另一方面,基于事件的解析,如 SAX 所做的那样,线性地查看文件,并在遇到结构化数据时简单地向用户进行回调,例如“这个元素开始”、“那个元素结束 , "some text here" 等。这样做的好处是它可以永远持续下去而不用担心输入文件的大小,但它的层次要低得多,因为它需要用户完成所有实际的处理工作(通过提供回电)。回到您最初的问题,术语“基于事件”是指解析器在遍历 XML 文件时引发的那些解析事件。

Wikipedia 文章有很多关于 SAX 解析阶段的详细信息。

于 2011-07-26T10:48:28.703 回答
7

在实际中:book.xml

<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
</bookstore>
  • DOM 将 xml 文档呈现为内存中的以下树结构
  • DOM 是 W3C 标准。
  • DOM 解析器适用于文档对象模型。
  • DOM 占用内存较多,首选用于小型 XML 文档
  • DOM 很容易向前或向后导航。

在此处输入图像描述


  • SAX 将 xml 文档呈现为基于事件start element:abc.end element:abc
  • SAX 不是 W3C 标准,它是由一组开发人员开发的。
  • SAX 不使用内存,这是大型 XML 文档的首选。
  • 向后导航是不可能的,因为它按顺序处理文档。
  • 事件发生在一个节点/元素上,它给出了所有子节点(拉丁节点,“结”)。

此 XML 文档在通过 SAX 解析器时,将生成如下事件序列

start element: bookstore
start element: book with an attribute category equal to cooking
start element: title with an attribute lang equal to en
Text node, with data equal to Everyday Italian
....
end element: title
.....
end element: book
end element: bookstore
于 2015-12-24T02:36:39.493 回答
3

SAX 和 DOM 都用于解析 XML 文档。两者各有优缺点,可以根据情况用在我们的编程中

萨克斯:

  1. 逐个节点解析

  2. 不将 XML 存储在内存中

  3. 我们无法插入或删除节点

  4. 从上到下遍历

DOM

  1. 在处理之前将整个 XML 文档存储到内存中

  2. 占用更多内存

  3. 我们可以插入或删除节点

  4. 向任何方向移动。

如果我们需要找到一个节点并且不需要插入或删除,我们可以使用 SAX 本身,否则 DOM 提供我们有更多的内存。

于 2016-12-07T04:13:39.827 回答