我有大量的XML。我需要解析该文件并将每个<elem/>
作为单个String保存到数据库中,但使用内存不足的方法,因为文件可能很大(~500MB)。怎么做 ?我正在寻找可行的例子。示例和我不太好的解决方案如下:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<header>...<header>
<elem>
<a/><b/><c>...</c>
</elem>
<elem>
<a>...</a><b/><c>...</c>
</elem>
<elem>
<a>...</a>
</elem>
...
</doc>
分手后:
{'<elem/>', '<elem/>', ...}
现在我正在使用SAX DefaultHandler,但我觉得这不是一个好的解决方案:
class DataFileParser extends DefaultHandler {
StringBuffer sb;
boolean sElem = false; // is elem
...
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(sElem) {
sb.append("<"+qName+">");
}
if (qName.equalsIgnoreCase("elem")) {
sb = new StringBuffer();
sb.append("<"+qName+">");
sElem = true;
}
...
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("elem")) {
sElem = false;
sb.append("</"+qName+">");
}
...
}
public void characters(char ch[], int start, int length) throws SAXException {
if(sElem) {
sb.append(new String(ch, start, length));
}
}
...
}
答案 0 :(得分:1)
事实上,使用SAX解析器是一个很好的解决方案。您可能需要考虑直接在endElement
中写入数据库。但是,如果您需要立即编写整个内容(例如在单个CLOB中),则无论使用何种解析器,都必须将其保存在某个位置。你可以放入临时文件。
在任何情况下,SAX解析器都是最有效的解决方案,因为内存占用主要取决于您处理的数据量而不是解析器实现。
答案 1 :(得分:1)
如果您不想编写任何低级Java代码,还有其他解决方案。例如,使用Saxon-EE,以下流式转换将起到作用:
<xsl:stylesheet xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
version="3.0">
<xsl:template name="main">
<xsl:for-each select="saxon:stream(doc('big.xml'))/*/elem">
<xsl:result-document href="out{position()}.xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>