java - 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>
标签并写入文件。
我的疑惑:
如果我使用 DOM 解析器,它会先将所有 xml 加载到内存中,然后查找
<body>
标记并写入文件吗?如果我使用 SAX 解析器执行此操作,它会
<body>
先在磁盘上查找标记本身,然后在找到它的那一刻开始从那里读取并继续加载到内存中直到</body>
?如果2个疑问是正确的,那么这种阅读是如何发生的?SAX 解析器是否逐字读取并将该单词保存在内存中一段时间并检查是否与代码正在寻找的标记匹配?因为标签的识别只能在内存中完成,但我认为无处可去。并继续从记忆中删除单词,直到找到选定的匹配项或标记
<body>
。找到它的那一刻,它开始将所有单词保存在内存中,直到它找到</body>
。
这是对的吗?
请纠正我..!
解决方案
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
中,如果标志为真,则收集标签文本内容(或将其写入磁盘)。另外,在endElement
flag 中需要设置为 false 以避免从其他标签中收集字符。
推荐阅读
- bash - gnuplot 内部列参数与容器 bash 脚本参数冲突
- html - 通过html模板中的CSS根据Django中的条件为特定值着色
- python - 如何从一个范围内获得两个不同的随机样本
- php - 将任意属性附加到 Blade x 组件,绑定属性à la Vue.js
- r - 如果在字符向量元素中找不到正则表达式匹配,如何返回 NULL?
- ios - 如果一个发布者没有产生任何值,如何让 CombineLatest3 返回结果?
- android - 为什么 Android Studio 中的 Image Asset 工具不会为 xxxhdpi 文件夹生成 PNG 文件?
- uwp - 如何使用 Windows Cloud Sync Engine API 支持删除?
- java - 需要从使用 java 3.12.0 驱动程序的 java 应用程序中的 mongoDB Atlas 中获取具有相同 first_name 的客户的 customerID 列表
- python - 为什么我的表单没有保存到管理数据库?