如何使用 Java 逐块解析大型 XML 文件

How to parse large XML file with Java, chunk by chunk

我正在尝试使用 Java 解析大型 XML 文件,一次解析一个块,这样服务器就不必将整个文件存储在内存中。

我的 Java 脚本代码使用 File API 切片函数对文件进行切片,并一次向服务器发送大约 2mb。我正在使用 AppEngine,所以无法保存到光盘。

例如,块一:

<message:DataSet>
   <series>...</series>
   <series>...</series>
   <series>...</series> (and so on, thousands)

块二、块三等直到 eof:

   <series>...</series>
   <series>...</series>
   <series>...</series> (more)

是否有某种类型的解析器可以保存 context/state/cursor,以便可以使用额外的数据块恢复解析?

或者,是否有一种解决方案可以在不将整个文件加载到内存的情况下解析大型 XML 文件?

parser = new Parser(previousState);
parser.parse(moreData);

对于任何有类似要求的人,我遇到了 Aalto XML 处理器,这几乎正是我所追求的。它具有所谓的非阻塞(异步)XML 解析。它向 StAX 添加了一个特殊事件,EVENT_INCOMPLETE,允许稍后输入更多输入。

例如:

<root>value</root>
AsyncXMLInputFactory inputF = new InputFactoryImpl();

//Parse part 1
byte[] input_part1 = "<root>val".getBytes("UTF-8");
AsyncXMLStreamReader<AsyncByteArrayFeeder> parser = inputF.createAsyncFor(input_part1);

//Process events here

//Parse part 2
byte[] input_part2 = "ue</root>".getBytes("UTF-8");
parser.getInputFeeder().feedInput(input_part2);

//Process more events here

更大的例子here

Aalto XML GitHub here

上的项目页面

更新: 还有 Woodstox,它有更多的特性,包括 P_INPUT_PARSING_MODE,它允许更宽松的解析(例如多个根元素)。两种解决方案均来自 FasterXML.