我有以下问题:
我有一个XML文件(大约1GB),并有重复向上和向下(即不连续的;一个接一个),以获得所需要的数据,并做一些关于它的操作。 起初,我用DOM Java包,但很明显,同时通过XML文件解析,JVM将达到其最大堆空间和停止。
为了克服这个问题,一种解决方案,我想出了,是要找到另一个解析器在XML遍历每个元素,然后我保存它在我的硬盘上的临时SQLite数据库的内容。 因此,在这种方式中,JVM的堆不超标,一旦所有的数据被填充,我忽略了XML文件,并继续在临时SQLite数据库我的操作。
有另一种方式我怎么能在手解决我的问题?
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 {
}
}
如果你不想被内存限制的约束呢,我当然建议你用你目前的做法,并存储在数据库中的一切。
XML文件的解析应该由做SAX parser
,因为大家都推荐的(包括我在内)。 这样就可以一次创建一个对象,并可以立即坚持到数据库中。
对于后处理(解决交叉引用),您可以使用SELECT
从数据库S,使主键,索引等,如果你觉得舒服,你可以使用ORM(的EclipseLink,休眠)也是如此。
其实我真的不建议SQLite的,它更容易建立一个MySQL服务器,并存储数据在那里。 后来,你甚至可以重复使用XML数据(如果你不删除)。
如果你想使用SAX更高级别的方法,这是非常棘手的程序,你可以看看流使用的是最新撒克逊-EE版本XSLT转换。 但是,你已经太含糊,你正在做的就知道这种方法是否适合你的特殊情况下,工作的精确处理。
如果你需要一个资源友好的方式来处理非常大的XML试试这个: http://www.xml2java.net/xml-to-java-data-binding-for-big-data/它可以让你在SAX处理数据的方式,但与得到的高级别事件(XML数据映射到Java的),并能直接在你的代码,这些对象工作的优势。 所以它结合了JAXB方便和SAX资源friendlyness。