部分读取xml文件

Ant*_*nyW 4 java xml file-io parsing gosu

我需要从大约100个长达200,000行的XML文件中读取前15行.有没有办法使用像BufferedReader这样的东西来有效地做到这一点?本问题中概述的步骤使用DocumentBuilder.parse(String); 这会尝试立即解析整个文件.

编辑:前15个元素包含有关文件的元数据(页面名称,最后编辑的日期等),我想将其解析为表格.

Bet*_*sta 7

这可能是你想要做的 - 正如我在评论中写的那样,使用SAX解析器,当满足你的停止条件时使用这个

如何在任何时候停止使用SAX解析xml文档?

编辑:

的test.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <first>
        <inner>data</inner>
    </first>
    <second>second</second>
    <third>third</third>
    <next>next</next>
</root>
Run Code Online (Sandbox Code Playgroud)

ReadXmlUpToSomeElementSaxParser.java

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ReadXmlUpToSomeElementSaxParser extends DefaultHandler {

    private final String lastElementToRead;

    public ReadXmlUpToSomeElementSaxParser(String lastElementToRead) {
        this.lastElementToRead = lastElementToRead;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // just for showing what is parsed
        System.out.println("startElement: " + qName);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (lastElementToRead.equals(qName)) {
            throw new MySaxTerminatorException();
        }
    }

    public static void main(String[] args) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();

        try {
            saxParser.parse("src/test.xml", new ReadXmlUpToSomeElementSaxParser("second"));
        } catch (MySaxTerminatorException exp) {
            // nothing to do, expected
        }
    }

    public class MySaxTerminatorException extends SAXException {
    }

}
Run Code Online (Sandbox Code Playgroud)

产量

startElement: root
startElement: first
startElement: inner
startElement: second
Run Code Online (Sandbox Code Playgroud)

为什么那更好?只是因为某些应用程序可以发送给您

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <first><inner>data</inner></first>
    <second>second</second>
    <third>third</third>
    <next>next</next>
</root>
Run Code Online (Sandbox Code Playgroud)

和线路导向的方法将失败...

我提供了不计算元素的解析器,以显示可以根据实现所需的业务逻辑来定义条件.

characters()警告

要读取元素中的数据,您可以使用character()方法,但请注意

SAX解析器可以在单个块中返回所有连续的字符数据,或者它们可以将其拆分为多个块

JavaDoc中阅读更多内容


小智 5

我建议研究一个流式 XML 解析器;流式 API 的用例扩展到读取数百 GB 的文件,而这些文件显然无法装入内存。

在 Java 中,StAX API 是本机 SAX API 的(相当大的)演变。浏览此处有关“即时”解析的教程:

http://tutorials.jenkov.com/java-xml/stax.html