我读了一些关于XML解析器的文章,遇到了SAX和DOM。

SAX是基于事件的,DOM是树模型——我不理解这两个概念之间的区别。

根据我的理解,基于事件意味着某种事件发生在节点上。比如,当点击一个特定的节点时,它会给出所有的子节点,而不是同时加载所有的节点。但在DOM解析的情况下,它将加载所有节点并生成树模型。

我的理解正确吗?

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


当前回答

简单地说:

DOM

树模型解析器(基于对象)(节点树)。 DOM将文件加载到内存中,然后解析该文件。 有内存限制,因为它在解析之前加载整个XML文件。 DOM是读写的(可以插入或删除节点)。 如果XML内容很小,则首选DOM解析器。 向后和向前的搜索是可能的搜索标签和评估 标签内的信息。这使得导航更容易。 运行时更慢。

SAX

基于事件的解析器(事件序列)。 SAX在读取文件时解析文件,即逐个节点解析。 没有内存限制,因为它不将XML内容存储在内存中。 SAX是只读的,即不能插入或删除节点。 当内存内容很大时,使用SAX解析器。 SAX从上到下读取XML文件,向后导航是不可能的。 运行时更快。

其他回答

就几句话……

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

DOM(文档对象模型):你把所有东西都加载到内存中——这是一个巨大的内存占用。即使是中等大小的文档也会让你的内存大开。但是你可以使用xpath和遍历树等等。

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

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

另一方面,SAX被设计用来处理几乎任何大小的XML输入。XML框架没有为您做确定文档结构和为所有节点、属性等准备大量对象的艰苦工作,SAX完全把这些工作留给了您。

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

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

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

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

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

当然,这种方法的缺点是,您需要自己做更多的簿记工作,这取决于您需要提取什么数据以及XML结构有多复杂。此外,您自然不能修改XML树的结构,因为您从来没有掌握整个XML树。

因此,一般来说,SAX适用于根据特定的“查询”对可能接收到的大量数据进行梳理,但不需要进行修改,而DOM更多的目的是在改变结构和内容方面提供充分的灵活性,但以更高的资源需求为代价。

实际上: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文档表示为基于事件的,如开始元素:abc,结束元素:abc。 SAX不是W3C标准,它是由一组开发人员开发的。 SAX不使用内存,首选用于大型XML文档。 向后导航是不可能的,因为它按顺序处理文档。 事件发生在节点/元素上,并给出所有子节点(拉丁语nodus, ' knot ')。

这个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

简单地说:

DOM

树模型解析器(基于对象)(节点树)。 DOM将文件加载到内存中,然后解析该文件。 有内存限制,因为它在解析之前加载整个XML文件。 DOM是读写的(可以插入或删除节点)。 如果XML内容很小,则首选DOM解析器。 向后和向前的搜索是可能的搜索标签和评估 标签内的信息。这使得导航更容易。 运行时更慢。

SAX

基于事件的解析器(事件序列)。 SAX在读取文件时解析文件,即逐个节点解析。 没有内存限制,因为它不将XML内容存储在内存中。 SAX是只读的,即不能插入或删除节点。 当内存内容很大时,使用SAX解析器。 SAX从上到下读取XML文件,向后导航是不可能的。 运行时更快。

好吧,你很接近了。

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

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

一般来说,DOM更容易使用,但在开始使用它之前需要解析整个XML。