1

在我正在开发的应用程序中,我必须处理非常大的 XML 文件(文件大小高达 2GB)...我想使用 Saxon java 库对这些文件运行一些 XQuery 命令。

我该如何做到这一点,以这样一种方式,一次只有文件中的一小部分记录保存在内存中,并且文件以如此小的数据集(而不是一次整个文件)进行处理 - 和同时,XQuery 命令的输出应该是正确的吗?我宁愿使用只有 0.5GB RAM 的机器来运行 XQuery 命令--> 所以不可能一次将整个 XML 加载到内存中。

4

2 回答 2

2

Saxon's support for streamed processing is actually stronger in XSLT than in XQuery, largely because the XSLT working group has been addressing this issue in designing XSLT 3.0. You can find information on the streaming capabilities of the product at

http://www.saxonica.com/documentation9.4-demo/index.html#!sourcedocs/streaming

Note these are available only in the commercial edition, Saxon-EE.

For simple "burst mode" streaming you can do things like:

for $e in saxon:stream(doc('big.xml')/*/record[@field='234']) return $e/name

By "burst mode" I essentially mean a query that operates over a large number of small disjoint subtrees of the source document.

于 2012-12-11T00:14:57.290 回答
1

实现此类功能的最佳方式(但很复杂)是限制可能的 XQuery 命令(即枚举所有可能的用例)。之后,对于每个文件处理一次,它使用 SAX 或 StAX 方式为整个 XML 文件创建内部“索引”,将搜索键映射到 XML 文件中的偏移量(开始和结束)。这些偏移量应该指向 XML 文件的一些小但格式良好的部分,可以独立加载和分析以检查它是否与指定的 XQuery 匹配。

另一种方法是将 XML 文件解析(再次使用 SAX 或 StAX)到一些基于磁盘的临时数据库(如 Apache Derby)并创建您自己的 XQuery => SQL 翻译器或解释器来访问此文件数据。你不会得到 OutOfMemoryException,但这种方法的性能......对于曾经使用过的文件可能不是最好的。

于 2012-12-10T14:32:35.883 回答