我需要处理大型XML文件,但我想对它进行相对较小的更改。我还希望程序遵守严格的内存限制。我们绝不能使用超过300Mb的ram。
是否有一个库允许我不将所有DOM保留在内存中,并在我遍历DOM的同时解析XML?
我知道你可以通过基于回拨的方法做到这一点,但我不希望如此。我想吃蛋糕也吃。我想使用DOM API,但是要懒惰地解析每个元素,以便使用DOM API的现有代码不必更改。
我想到了这个问题的两种可能方法:
getChildren()
都会解析下一段XML。其中两种方法是可以接受的,是否有现成的解决方案。
我正在寻找原生解决方案,但我会对听到其他语言的图书馆感兴趣。
答案 0 :(得分:2)
我想使用DOM API,但是要懒惰地解析每个元素,以便使用DOM API的现有代码不必更改。
您想要一个流式DOM风格的API吗?这样的事情通常不存在,并且有充分的理由:如果不是不可能的话,它实际上很难实现。
XML通常用于单向读取:从前到后。您的建议是需要能够随机访问XML文件。
我想你可以在构建元素表的地方做一些事情,文件偏移量指向文件中该元素的位置。但在那时,您已经或多或少地阅读并解析了该文件。除非您的大部分数据都在文本元素中(完全可能),否则您也可以使用DOM。
真的,只要重写现有代码以使用xmlReader或SAX风格的API,你会好得多。
答案 1 :(得分:2)
听起来你想要的东西与Streaming API for XML (StAX)类似。
虽然它不使用标准DOM API,但它在原理上与您的“getChildren()”方法类似。它没有DOM方法的内存开销,也没有回调(SAX)方法的复杂性。
Wikipedia page for StAX上有许多实现链接,其中大部分都是针对Java的,但C ++也有一对实现 - Ambiera irrXML和Llamagraphics LlamaXML。
编辑:由于您提到文档的“小更改”,如果您不需要将文档内容用于其他任何内容,您可能还会考虑Streaming Transformations for XML (STX)(在this XML.com introduction to STX中描述)。 STX对XSLT来说就像SAX / StAX对DOM一样。
答案 2 :(得分:1)
如何进行流式转换是一个很大的,开放的,未解决的问题。根据您准备接受的限制,有许多部分解决方案。例如,Saxon-EE的当前版本能够以流式方式进行一些XSLT转换:请参阅http://www.saxonica.com/html/documentation/sourcedocs/streaming.html。另外,如前所述,有STX(尽管实现并不特别成熟)。
你的标题建议你想用C ++编写转换。这是一个严重的限制,因为它很好意味着程序员必须应对复杂性而不是将其留给转换引擎。您当然可以使用类似SAX或类似StAX的解析器API手动编码流转换,但这两者都很难,每个案例都需要从头开始处理。
Google用于“流式XML转换”