在JAVA中解析大型XML文档

cgv*_*val 11 java xml sqlite xml-parsing

我有以下问题:

我有一个XML文件(大约1GB),并且必须上下迭代(即不顺序;一个接一个),以获得所需的数据并对其进行一些操作.最初,我使用了DOM Java包,但很明显,在解析XML文件时,JVM达到了最大堆空间并停止了.

为了克服这个问题,我提出的解决方案之一是找到另一个迭代XML中每个元素的解析器,然后将它的内容存储在硬盘上的临时SQLite数据库中.因此,通过这种方式,不会超出JVM的堆,并且一旦填满所有数据,我就会忽略XML文件并继续对临时SQLite数据库执行操作.

还有另一种方法可以解决我的问题吗?

Nis*_*hth 12

SAX(XML的简单API)将在这里您提供帮助.

与DOM解析器不同,SAX解析器不会创建XML文档的内存中表示,因此更快并且使用更少的内存.相反,SAX解析器通过调用回调来通知客户端XML文档结构,即通过调用org.xml.sax.helpers.DefaultHandler提供给解析器的实例上的方法 .

这是一个示例实现:

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
DefaultHandler handler = new MyHandler();
parser.parse("file.xml", handler);
Run Code Online (Sandbox Code Playgroud)

MyHandler您在何处定义生成文档/元素的开始/结束等事件时要采取的操作.

class MyHandler extends DefaultHandler {

    @Override
    public void startDocument() throws SAXException {
    }

    @Override
    public void endDocument() throws SAXException {
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
    }

    // To take specific actions for each chunk of character data (such as
    // adding the data to a node or buffer, or printing it to a file).
    @Override
    public void characters(char ch[], int start, int length)
            throws SAXException {
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 如果你曾经做过SAX解析,你可能知道`characters()`方法也非常重要,你必须对字符数据进行**缓冲**,因为不保证内容数据是在一个块(即两个`character()`调用可以立即完成).我认为值得一提. (2认同)
  • 我并不是说我的解决方案是完整的。这只是一个基本的实现。不过谢谢你指出。我会用那个更新我的答案。 (2认同)