Java延迟读取XML文件?

Java延迟读取XML文件?,java,xml,Java,Xml,我想知道我怎么能懒洋洋地读取一个不适合Java内存的大型XML文件。让我们假设文件格式正确,并且我们不必进行第一次检查。有人知道如何在Java中做到这一点吗 这是我的假文件(真实文件是Wikipedia转储,50+Gb): 一些数据。。。。。。。 更多数据。。。。。。。。 我用一个XML库尝试了这一点,该库应该能够做到这一点,但它正在将整个过程加载到内存中>:O DOMParser domParser = new DOMParser(); //This is supposed to make

我想知道我怎么能懒洋洋地读取一个不适合Java内存的大型XML文件。让我们假设文件格式正确,并且我们不必进行第一次检查。有人知道如何在Java中做到这一点吗

这是我的假文件(真实文件是Wikipedia转储,50+Gb):


一些数据。。。。。。。
更多数据。。。。。。。。
我用一个XML库尝试了这一点,该库应该能够做到这一点,但它正在将整个过程加载到内存中>:O

DOMParser domParser = new DOMParser();
//This is supposed to make it lazy-load the file, but it's not working
domParser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
//Library says this needs to be set to use defer-node-expansion
domParser.setProperty("http://apache.org/xml/properties/dom/document-class-name", "org.apache.xerces.dom.DocumentImpl");

//THIS IS LOADING THE WHOLE FILE
domParser.parse(new InputSource(wikiXMLBufferedReader));

Document doc = domParser.getDocument();
NodeList pages = doc.getElementsByTagName("page");

for(int i = 0; i < pages.getLength(); i++) {
    Node pageNode = pages.item(i);
    //do something with page nodes
}
DOMParser-DOMParser=new-DOMParser();
//这应该使它延迟加载文件,但它不工作
domParser.setFeature(“http://apache.org/xml/features/dom/defer-node-expansion“,对);
//库说这需要设置为使用延迟节点扩展
domParser.setProperty(“http://apache.org/xml/properties/dom/document-class-name“,”org.apache.xerces.dom.DocumentImpl“;
//这是加载整个文件
parse(新的InputSource(wikiXMLBufferedReader));
Document doc=domParser.getDocument();
节点列表页面=doc.getElementsByTagName(“页面”);
对于(int i=0;i
有人知道怎么做吗?或者,在尝试使用这个特定的Java XML库时,我做错了什么


谢谢。

您应该看看Java中的SAX解析器。DOM解析器用于读取整个XML,加载到内存中,并从中创建java对象。SAX解析器串行解析XML文件,并使用基于事件的机制来处理数据。看看这些区别


到SAX教程。希望能有所帮助。

如果您准备购买Saxon EE许可证,那么您可以发出简单的查询“copy of(//page)”,并将执行选项设置为启用流式传输,它将返回一个遍历树序列的迭代器,每个树都以页面元素为根;当您推进迭代器时,将获取每个树,当您完成迭代器时,将对其进行垃圾收集。(假设您真的想用Java进行处理;当然,您也可以用XQuery或XSLT进行处理,这可能会节省许多代码行。)


如果您的时间比金钱多,并且想要一个自制的解决方案,那么就编写一个SAX过滤器,它接受来自XML解析器的解析事件,并将它们发送到DocumentBuilder;每次点击页面元素的startElement事件时,打开一个新的DocumentBuilder;通知相应的endElement事件后,抓取DocumentBuilder构建的树,并将其传递给Java应用程序进行处理。

延迟节点扩展会延迟节点的扩展,直到您使用它,但它不会在以后从内存中清除它,因此它不会执行您想要的操作。
DOMParser domParser = new DOMParser();
//This is supposed to make it lazy-load the file, but it's not working
domParser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
//Library says this needs to be set to use defer-node-expansion
domParser.setProperty("http://apache.org/xml/properties/dom/document-class-name", "org.apache.xerces.dom.DocumentImpl");

//THIS IS LOADING THE WHOLE FILE
domParser.parse(new InputSource(wikiXMLBufferedReader));

Document doc = domParser.getDocument();
NodeList pages = doc.getElementsByTagName("page");

for(int i = 0; i < pages.getLength(); i++) {
    Node pageNode = pages.item(i);
    //do something with page nodes
}