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

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

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

我的理解正确吗?

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


当前回答

就几句话……

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

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

其他回答

简单地说:

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。

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

也许有必要简要回顾一下:

The document object model (DOM) is an abstract data model that describes a hierarchical, tree-based document structure; a document tree consists of nodes, namely element, attribute and text nodes (and some others). Nodes have parents, siblings and children and can be traversed, etc., all the stuff you're used to from doing JavaScript (which incidentally has nothing to do with the DOM). A DOM structure may be serialized, i.e. written to a file, using a markup language like HTML or XML. An HTML or XML file thus contains a "written out" or "flattened out" version of an abstract document tree. For a computer to manipulate, or even display, a DOM tree from a file, it has to deserialize, or parse, the file and reconstruct the abstract tree in memory. This is where parsing comes in.

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

On the other hand, event-based parsing, as done by SAX, looks at the file linearly and simply makes call-backs to the user whenever it encounters a structural piece of data, like "this element started", "that element ended", "some text here", etc. This has the benefit that it can go on forever without concern for the input file size, but it's a lot more low-level because it requires the user to do all the actual processing work (by providing call-backs). To return to your original question, the term "event-based" refers to those parsing events that the parser raises as it traverses the XML file.

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

实际上: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

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

SAX:

逐个节点解析 不将XML存储在内存中 我们不能插入或删除一个节点 从上到下遍历

DOM

在处理之前将整个XML文档存储到内存中 占用更多内存 我们可以插入或删除节点 任意方向。

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