首页 > 解决方案 > SAX 解析器如何工作?

问题描述

我是 XML 解析的新手。在执行一项需要解析大 XML 文件的任务时。因此,在尝试制定一个好的解决方案时,我遇到了这两个术语,DOM 和 SAX。这两者都是两种不同类型的 XML 解析。我在这里对 SAX 解析有点困惑。阅读了很多,但仍然感到困惑。

让我们以下面的 XML 为例

 <?xml version="1.0" encoding="UTF-8"?>
<note>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
</note>

可以说,我只想读取所有<body>标签并写入文件。

我的疑惑:

  1. 如果我使用 DOM 解析器,它会先将所有 xml 加载到内存中,然后查找<body>标记并写入文件吗?

  2. 如果我使用 SAX 解析器执行此操作,它会<body>先在磁盘上查找标记本身,然后在找到它的那一刻开始从那里读取并继续加载到内存中直到</body>

  3. 如果2个疑问是正确的,那么这种阅读是如何发生的?SAX 解析器是否逐字读取并将该单词保存在内存中一段时间​​并检查是否与代码正在寻找的标记匹配?因为标签的识别只能在内存中完成,但我认为无处可去。并继续从记忆中删除单词,直到找到选定的匹配项或标记<body>。找到它的那一刻,它开始将所有单词保存在内存中,直到它找到</body>

这是对的吗?
请纠正我..!

标签: javaxmldomsax

解决方案


StAX(或拉解析器)将更适合您描述的用例。DOM 读取整个文档,SAX 解析器生成您需要处理的事件,它们不在内存中存储任何内容(除了它们的内部)。使用 SAX,您需要使用某些方法实现内容处理程序,这也意味着您需要维护事件流的状态。例如,您发布的文档的第一块将生成以下(简化的)事件:

startDocument
startElement(note)
startElement(Desc)
startElement(to)
characters(Tove) // might come as multiple chunks
endElement(to)
...
endDocument

因此,如果标签名称为,则需要检查 startElement body(如果您只想要body其中的元素,note -> Desc则需要跟踪所有开始/结束元素)并设置一个标志。在characters中,如果标志为真,则收集标签文本内容(或将其写入磁盘)。另外,在endElementflag 中需要设置为 false 以避免从其他标签中收集字符。


推荐阅读