我是XML解析的新手。在执行一项需要解析Big 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>
标签本身,一旦找到它,便开始从那里读取并继续加载到内存中,直到{{1 }}?
如果2个怀疑是正确的,那么这种阅读是如何发生的? SAX解析器是否逐字读取并将该字保留在内存中一段时间,并检查是否与代码正在寻找的标记匹配?因为标签的识别只能在内存中完成,但我认为这无处不在。并继续从内存中拉下单词,直到找到所选的匹配项或标记</body>
。找到它的那一刻,它开始将所有单词保留在内存中,直到找到<body>
。
正确吗?
请纠正我..!
答案 0 :(得分:2)
StAX(或拉解析器)将在您描述的用例中更好地工作。 DOM读取整个文档,SAX解析器生成您需要处理的事件,它们在内存中没有任何内容(内部消息除外)。使用SAX,您需要编写一个实现certain methods的内容处理程序,这还意味着您需要维护事件流的状态。例如,您发布的文档的第一块将生成以下(简化的)事件:
startDocument
startElement(note)
startElement(Desc)
startElement(to)
characters(Tove) // might come as multiple chunks
endElement(to)
...
endDocument
因此,如果标记名称为body
,则需要签入startElement(如果只需要body
中的note -> Desc
个元素,则需要跟踪所有开始/结束元素)并设置一个标志。在characters
中,如果该标志为true,则收集标签文本内容(或将其写入磁盘)。另外,在endElement
中,该标志需要设置为false,以避免从其他标签中收集字符。
答案 1 :(得分:1)
DOM分析器将整个XML文档加载到内存中,并通过Java API使您可以使用它。这种方法的优点是易于使用和理解,但效率不高,因为:
SAX解析器较难使用,但性能可能更高。 SAX解析器不将任何内容存储在内存中。而是调用您提供的代码来处理遇到的每个XML元素。对于您的情况,它将回叫您说“我找到了