SAX 和 DOM 有什么区别?

What is the difference between SAX and DOM?

提问人:user414967 提问时间:7/26/2011 最后编辑:eebbesenuser414967 更新时间:8/16/2018 访问量:248623

问:

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

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

据我所知,基于事件意味着节点发生了某种事件。就像当单击特定节点时,它将提供所有子节点,而不是同时加载所有节点。但是在 DOM 解析的情况下,它将加载所有节点并制作树模型。

我的理解正确吗?

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

XML 解析 saxparser domparser

评论

0赞 Bob77 1/31/2019
正确地说,DOM 不是解析器。任何给定的基于 DOM 的软件都可能包含也可能不包含标记解析,大多数 HTML DOM 软件都包含标记解析。但是 DOM 是一个完全独立的东西,可能根本不与任何序列化格式相关联。

答:

337赞 sparkymat 7/26/2011 #1

好吧,你很接近。

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

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

一般来说,DOM 更易于使用,但在开始使用之前会分析整个 XML 的开销。

评论

147赞 Richard H 7/26/2011
+1 - 澄清一下:使用DOM解析器,其中包含适合RAM的较小文件。将 SAX 解析器用于不会的大型文件。
0赞 user414967 7/26/2011
谢谢@spartkymat。但是,在基于 SAX 事件的情况下,SAX 解析器是否能够知道特定的子节点是特定父节点的子节点?或者只是它会解析?例如。我有一个<公司>孩子是<员工>。因此,在这种情况下,这些公司和员工将被解析,还是会显示公司是员工的父母的关系?
4赞 sparkymat 7/26/2011
它只会解析。您必须自己维护此类信息(通过状态机或其他方式)。使用 DOM 解析器的更多理由(如果资源允许):-)。
1赞 antred 10/13/2017
@Richard H 我认为,任何使用如此庞大的 XML 文件以至于无法放入 RAM 的人都在做非常非常错误的事情。
2赞 zhiyuan_ 11/2/2018
加载 40m 大小的 excel,使用 SAX 解析器时使用 200m 内存,使用 DOM 解析器时使用 9g 内存。
16赞 Kerrek SB 7/26/2011 #2

你正在比较苹果和梨。SAX 是一个解析器,用于解析序列化的 DOM 结构。有许多不同的解析器,“基于事件”是指解析方法。

也许有一个小小的回顾是有道理的:

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

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

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

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

另一方面,SAX 所做的基于事件的解析会线性地查看文件,并在遇到结构性数据时简单地对用户进行回调,例如“此元素已启动”、“该元素已结束”、“此处存在一些文本”等。这样做的好处是它可以永远持续下去,而不用担心输入文件大小,但它的级别要低得多,因为它需要用户完成所有实际的处理工作(通过提供回调)。回到原来的问题,术语“基于事件”是指解析器在遍历 XML 文件时引发的那些解析事件

维基百科文章有许多关于 SAX 解析阶段的细节。

38赞 Daniel Schneller 7/26/2011 #3

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

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

另一方面,SAX 旨在处理几乎任何大小的 XML 输入。SAX 没有让 XML 框架为您完成艰苦的工作,例如弄清楚文档的结构并为所有节点、属性等准备可能的大量对象,而 SAX 完全将其留给您。

它基本上所做的是从顶部读取输入,并在发生某些“事件”时调用您提供的回调方法。事件可能命中开始标记、标记中的属性、在元素中查找文本或遇到结束标记。

SAX 固执地读取输入,并以这种方式告诉您它看到了什么。由您来维护所需的所有状态信息。通常这意味着您将构建某种状态机。

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

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

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

当然,这种方法的缺点是,您需要自己做更多的簿记工作,具体取决于需要提取的数据以及 XML 结构的复杂程度。此外,您自然不能修改 XML 树的结构,因为您从未将其作为一个整体掌握在手里。

因此,一般来说,SAX 适合于梳理您收到的潜在大量数据,并考虑到特定的“查询”,但不需要修改,而 DOM 更旨在让您在更改结构和内容方面具有充分的灵活性,但代价是更高的资源需求。

113赞 Bohemian 7/26/2011 #4

短短几句话...

SAXSimple API for XML):是基于流的处理器。在任何时候,内存中都只有一小部分,并且可以通过为诸如此类事件实现回调代码来“嗅探”XML流。它几乎不使用内存,但你不能做“DOM”的东西,比如使用 xpath 或遍历树。tagStarted()

DOMDocument Object Model):你把整个东西都加载到内存中——这是一个巨大的内存消耗。即使是中等大小的文档,您也可以破坏内存。但是你可以使用 xpath 并遍历树等。

78赞 Chinmoy Mishra 10/3/2013 #5

这里用更简单的话来说:

DOM的

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

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

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

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

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

  • 可以进行向后和向前搜索,以搜索标签和评估 标签内的信息。因此,这提供了导航的便利性。

  • 运行时速度较慢。

萨克斯管

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

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

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

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

  • 当内存内容较大时,请使用 SAX 分析器。

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

  • 运行时速度更快。

评论

0赞 Kunal Gupta 7/22/2016
完善。。。期待一些点数的答案。干得好:)
0赞 Michael Gehling 2/2/2021
SAX 是更快还是 DOM 取决于您需要做什么。如果你只需要处理一小部分节点,SAX 通常更快,如果你必须在所有节点上工作,DOM 通常更快。但归根结底,这也很大程度上取决于数据的大小,当然......如果文档太大,超出了可用内存,那么 DOM 就是一个坏主意。
7赞 Premraj 12/24/2015 #6

实际上:书.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:abcend element:abc
  • SAX 不是 W3C 标准,它是由一组开发人员开发的。
  • SAX 不使用内存,这是大型 XML 文档的首选。
  • 向后导航是不可能的,因为它按顺序处理文档。
  • 事件发生在一个节点/元素上,它给出了所有子节点(拉丁语 nodus,“结”)。

此 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

评论

0赞 1252748 12/27/2015
为什么上面是 DOM 解析的可视化表示?查看 XML,看起来 an 应该与它的 with 和 平行。这只是一种节省空间的技术,还是有意建立亲子关系?attr: "lang"element: <title>attr<element><book>category
0赞 Premraj 12/27/2015
它只是一种节省空间的技术
3赞 Kavita Jain 12/7/2016 #7

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

萨克斯管:

  1. 逐个节点解析

  2. 不将 XML 存储在内存中

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

  4. 从上到下的遍历

DOM的

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

  2. 占用更多内存

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

  4. 向任何方向遍历。

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