用JAVA解析大型XML文档
我有以下问题: 我有一个XML文件(大约1GB),必须上下迭代(即不连续;一个接一个),以获取所需的数据并对其执行一些操作。最初,我使用了domjava包,但很明显,在通过XML文件进行解析时,JVM达到了最大堆空间并停止了 为了克服这个问题,我提出的解决方案之一是找到另一个解析器,该解析器迭代XML中的每个元素,然后将其内容存储在硬盘上的临时SQLite数据库中。因此,通过这种方式,不会超出JVM的堆,并且一旦填充了所有数据,我将忽略XML文件并继续对临时SQLite数据库进行操作 有没有其他方法可以解决我手头的问题?将在这里帮助您 与DOM解析器不同,SAX解析器不在内存中创建 表示XML文档,因此速度更快,使用更少 记忆。相反,SAX解析器将XML文档通知客户机 通过调用回调,也就是说,通过调用用JAVA解析大型XML文档,java,xml,sqlite,xml-parsing,Java,Xml,Sqlite,Xml Parsing,我有以下问题: 我有一个XML文件(大约1GB),必须上下迭代(即不连续;一个接一个),以获取所需的数据并对其执行一些操作。最初,我使用了domjava包,但很明显,在通过XML文件进行解析时,JVM达到了最大堆空间并停止了 为了克服这个问题,我提出的解决方案之一是找到另一个解析器,该解析器迭代XML中的每个元素,然后将其内容存储在硬盘上的临时SQLite数据库中。因此,通过这种方式,不会超出JVM的堆,并且一旦填充了所有数据,我将忽略XML文件并继续对临时SQLite数据库进行操作 有没有其他
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 {
}
}
如果您不想受到内存限制的约束,我当然建议您使用当前的方法,并将所有内容存储在数据库中 XML文件的解析应该由
SAX解析器
完成,正如每个人(包括我)所建议的那样。通过这种方式,您可以一次创建一个对象,并且可以立即将其持久化到数据库中
对于后处理(解决交叉引用),您可以使用从数据库中选择
s,生成主键、索引等。如果您对此感到满意,也可以使用ORM(Eclipse、Hibernate)
实际上我并不推荐SQLite,它更容易设置MySQL服务器,并将数据存储在那里。以后,您甚至可以重用XML数据(如果不删除)。如果您想使用比SAX更高级别的方法(编程可能非常棘手),可以使用最新的Saxon EE版本查看流式XSLT转换。但是,您对正在进行的精确处理过于模糊,无法知道这是否适用于您的特定情况。如果您需要一种资源友好的方法来处理非常大的xml,请尝试以下方法:
它允许您以SAX方式处理数据,但具有获取高级事件(映射到java的xml数据)以及能够直接在代码中使用这些对象的优势。因此,它结合了jaxb便利性和SAX资源友好性 使用jaxb解析XML正如其他人所说,您需要使用SAX解析器而不是DOM解析器,它将完全满足您的需要。请阅读以下内容:如果无法保存整个DOM树,则必须找到一种按顺序进行处理的方法。可能吗?你能展示一个XSLT来做你需要的吗?对于解析大的xml文件,总是使用SAX解析器。参考以下链接,您所说的非顺序操作是什么意思?XML中是否有不同的数据,并且它们之间有交叉引用?无论使用哪种XML解析器,都必须将所有数据存储在内存中。与其尝试向JVM提供更多的
-Xmx
,它应该可以轻松处理1G。如果您曾经进行过SAX解析,您可能知道characters()
方法也非常重要,您必须对字符数据进行缓冲,因为不能保证在一个块(即两个character()中处理内容数据)
呼叫可以立即完成)。我认为这是值得一提的。我并不是说我的解决方案是完整的。这只是一个初步的实现。谢谢你的指点。我将更新我的答案。我想知道为什么有人会相信安装整个数据库服务器比使用嵌入式数据库更容易,因为嵌入式数据库只需要包含一个JAR文件,而不需要安装任何东西。我认为对于这个用例来说,一个单独的数据库服务器会有点过头。也许还有其他一些很好的理由使用数据库服务器,但更容易安装?真的吗?@vanje我不是指甲骨文:)我们说的是MySQL。说真的,我不相信任何开发人员都会遇到设置MySQL服务器的问题。我认为每个开发人员都应该能够执行Oracle和MySQL的基本安装。我同意你的看法,Oracle比MySQL复杂得多。但这不是重点。您将MySQL与SQLite进行了比较,并指出MySQL将更易于安装。但你没有提到你的观点中什么更容易。