为什么sax解析比dom解析更快?stax是如何工作的?

and*_*bd1 11 java xml stax dom sax

有点相关:来自java的libxml2

是的,这个问题相当啰嗦 - 对不起.我保持尽可能密集.我把问题加粗了,以便在阅读整篇文章之前更容易窥视.

为什么sax解析比dom解析更快? 我唯一能想到的是w/sax你可能忽略了大部分传入数据,因此不会浪费时间处理你不关心的xml部分.IOW - 解析w/SAX后,无法重新创建原始输入. 如果您编写SAX解析器以便它占据每个xml节点(并因此可以重新创建原始节点),那么它不会比DOM更快吗?

我问的原因是我正在尝试更快地解析xml文档.我需要在解析后访问整个xml树.我正在编写一个插入第三方服务的平台,所以我无法预测xml文档的哪些部分需要以及哪些部分不需要.我甚至不知道传入文件的结构.这就是为什么我不能使用jaxb或sax.内存占用对我来说不是问题,因为xml文档很小,我一次只需要1个内存.这是解析这个相对较小的xml文档所花费的时间.我之前没有使用过stax,但也许我需要进一步调查,因为它可能是中间地带? 如果我理解正确, 通过这种方式,原始的解析时间可能很快,但每次我要求它遍历尚未遍历的树的一部分时,就是处理发生的时候?

如果您提供了回答大多数问题的链接,我会接受您的回答(如果他们已在其他地方回答,您无需直接回答我的问题).

更新:我在sax中重写了它,并在avg 2.1 ms上解析文档.这比dom所采用的2.5毫秒有所改善(快16%),但这并不是我(等人)猜到的那么大.

谢谢

bdo*_*han 15

假设您除了解析文档之外什么都不做,不同解析器标准的排名如下:

1. StAX是最快的

  • 该事件将报告给您

接下来是SAX

  • 它完成了StAX所做的一切以及内容自动实现(元素名称,命名空间,属性......)

3. DOM是最后的

  • 它完成SAX所做的一切,并将信息作为Node的实例呈现.

你的用例

  • 如果需要维护所有XML,DOM是标准表示.它与XSLT转换(javax.xml.transform),XPath(javax.xml.xpath)和模式验证(javax.xml.validation)API 完全集成.但是,如果性能是关键,那么您可以使用StAX构建自己的树结构,而不是DOM解析器可以构建DOM.

  • StAX将报告该元素已启动,如果您从未要求元素名称或URI,那么该数据不需要被实现为String对象.另一方面,SAX解析器将数据作为String对象实现为事件的一部分. (4认同)
  • 我从未看过StAX解析器的内部.如果只考虑名称空间URI方面.实现的令牌可以是"foo:bar".SAX解析器将"foo"前缀解析为命名空间URI并报告它,StAX解析器不需要对令牌执行该工作,因此执行速度更快. (2认同)

mik*_*obi 11

DOM解析要求您将整个文档加载到内存中,然后遍历树以查找所需的信息.

你需要做的基本的IO SAX只需要尽可能多的内存,你可以提取你需要的文件正在读取信息.由于SAX是面向流的,因此您甚至可以处理仍由另一个进程写入的文件.

  • @ andersonbd1,读你的问题,在我看来,你真的不明白SAX和DOM之间的区别,而这是你不知道答案的一个因素.鉴于此,mikerobi的答案是合理的.你可能确实理解了这种差异,但你的问题并没有说清楚.声称他没有阅读问题或给出一个轻率的答案是不必要的. (5认同)
  • @ andersonbd1,我准备好了你的问题,对不起,你不明白我的回答.对我来说很明显,一个需要更多内存的进程,并且在完全解析之前不会让你访问数据的进程比一个需要很少内存的进程要慢,并且允许你几乎和它一样快地访问数据可以读. (2认同)

eri*_*son 11

SAX更快,因为DOM解析器经常使用SAX解析器在内部解析文档,然后做创建和操作对象来表示每一个节点,即使应用程序不关心他们的额外工作.

直接使用SAX的应用程序可能比DOM"解析器"更有效地利用信息集.

StAX是一种快乐的媒介,其中应用程序获得比SAX的事件驱动方法更方便的API,但不会产生创建完整DOM的低效率.