在我正在处理的应用程序中,我必须处理非常大的XML文件(文件大小多达2GB)...我想使用Saxon java库对这些文件运行一些XQuery命令。
我该怎么做,以这种方式,一次只有文件中的一小组记录保存在内存中,文件在如此小的数据集中处理(而不是一次整个文件) - 同时,XQuery命令的输出应该是正确的?我更喜欢使用只有0.5GB RAM的机器来运行XQuery命令 - >所以它不可能一次将整个XML加载到内存中。
答案 0 :(得分:2)
Saxon对流处理的支持实际上在XSLT中比在XQuery中更强,主要是因为XSLT工作组在设计XSLT 3.0时一直在解决这个问题。您可以在
找到有关产品流功能的信息http://www.saxonica.com/documentation9.4-demo/index.html#!sourcedocs/streaming
请注意,这些仅适用于商业版Saxon-EE。
对于简单的“突发模式”流式传输,您可以执行以下操作:
对于撒克逊人的$ e:stream(doc('big.xml')/ * / record [@ field ='234'])返回$ e / name
通过“突发模式”,我实质上是指对源文档的大量小的不相交子树进行操作的查询。
答案 1 :(得分:1)
达到此类功能的最佳方式(但复杂)是限制可能的XQuery命令(即枚举所有可能的用例)。之后,对于每个文件进程,它使用SAX或StAX方式为整个XML文件创建内部“索引”,将搜索键映射到XML文件中的偏移(开始和结束)。这些偏移量应指向XML文件的一些小但结构良好的部分,可以单独加载并进行分析以检查它是否与指定的XQuery匹配。
替代方法是将(再次使用SAX或StAX)XML文件解析为一些基于磁盘的临时数据库(如Apache Derby)并创建自己的XQuery => SQL转换器或解释器来访问此文件数据。你不会得到OutOfMemoryException,但是这种方法的性能......可能不适合曾经使用过的文件。