用java解析非常大的XML文档(还有更多)
(以下所有内容都将用Java编写)
我必须构建一个应用程序,将潜在的非常大的XML文档作为输入。文档是加密的——不是使用XMLsec,而是使用我的客户机之前存在的加密算法——将分三个阶段进行处理:
首先,将根据上述算法对流进行解密
其次,扩展类(由第三方编写到我提供的API)将读取文件的某些部分。读取的量是不可预测的——尤其是不能保证在文件头中,但可能发生在XML中的任何一点
最后,另一个扩展类(相同的交易)将把输入XML细分为1。。n子集文档。这些可能会在某种程度上与第二个操作所处理的文档部分重叠,即:我相信我需要倒带我用来处理这个对象的任何机制
我的问题是:
有没有一种方法可以在不将整段数据一次性读入内存的情况下做到这一点?显然,我可以将解密实现为一个输入流过滤器,但我不确定是否有可能以我描述的方式解析XML;通过浏览收集第二步信息所需的尽可能多的文档,然后重绕文档并再次传递,将其拆分为作业,理想情况下,释放文档中传递后不再使用的所有部分
# 1 楼答案
这听起来像是StAX的工作。StAX是一个pull解析器,这意味着它的工作方式或多或少类似于SAX之类的基于事件的解析器,但您可以更好地控制何时停止读取、要提取哪些元素
这个解决方案的可用性在很大程度上取决于扩展类实际在做什么,如果你能控制它们的实现等等
主要的一点是,如果文档非常大,可能需要使用基于事件的解析器,而不是基于树的解析器,因此不会占用大量内存
StAX的实现可以从SUN(SJSXP)、Codehaus或其他一些提供者那里找到
# 2 楼答案
看看XOM图书馆。您正在查找的示例是源发行版的samples目录中的
StreamingExampleExtractor.java
。这展示了一种对大型xml文档执行流式解析的技术,该技术仅用于构建特定节点、处理它们并丢弃它们。它与sax方法非常相似,但内置了更多的解析功能,因此可以非常轻松地实现流解析如果你想在更高层次上工作,可以看看NUX。这提供了一个高级流式xpath API,它只将计算xpath所需的数据量读入内存
# 3 楼答案
我将编写
InputStream
的自定义实现,对文件中的字节进行解密,然后使用SAX解析从流中导出的XML# 4 楼答案
斯塔克斯是正确的方法。我建议你看看Woodstox
# 5 楼答案
您可能对XOM感兴趣: