12

我有以下问题:

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

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

还有其他方法可以解决我手头的问题吗?

4

4 回答 4

13

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);

您在哪里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 {
    }

}
于 2013-02-28T10:02:27.137 回答
3

如果您不想受内存限制的限制,我当然建议您使用当前的方法,并将所有内容存储在数据库中。

SAX parser正如每个人(包括我)所建议的那样,XML 文件的解析应该由 a 完成。这样,您一次可以创建一个对象,并且可以立即将其持久化到数据库中。

对于后处理(解决交叉引用),您可以使用SELECT数据库中的 s,制作主键、索引等。如果您觉得舒服,也可以使用 ORM(Eclipselink、Hibernate)。

其实我不是很推荐 SQLite,它更容易设置一个 MySQL 服务器,并将数据存储在那里。以后您甚至可以重用 XML 数据(如果您不删除)。

于 2013-02-28T11:30:53.537 回答
1

如果您想使用比 SAX 更高级别的方法(编程可能非常棘手),您可以使用最近的 Saxon-EE 版本查看流式 XSLT 转换。但是,您对正在执行的精确处理过于模糊,不知道这是否适用于您的特定情况。

于 2013-02-28T14:49:44.787 回答
0

如果您需要一种资源友好的方法来处理非常大的 xml,请尝试以下操作: http ://www.xml2java.net/xml-to-java-data-binding-for-big-data/ 它允许您在 SAX 中处理数据方式,但具有获取高级事件(映射到 java 的 xml 数据)并能够直接在代码中使用这些对象的优势。因此它结合了 jaxb 的便利性和 SAX 资源友好性。

于 2015-02-20T15:35:23.573 回答