0

我有巨大的 XML。我需要解析该文件并将每个<elem/>字符串作为单个字符串保存到数据库中,但使用内存占用低的方法,因为文件可能很大(~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));
               }
        }


 ...
}
4

2 回答 2

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>
于 2012-04-26T08:31:59.407 回答
1

事实上,使用 SAX 解析器是一个很好的解决方案。您可能需要考虑直接在endElement. 但是,如果您需要一次编写整个内容(例如在单个 CLOB 中),则无论您使用什么解析器,都必须将其保存在某个地方。您可以为此放入临时文件。

在任何情况下,SAX 解析器都是最有效的解决方案,因为内存占用主要取决于您处理的数据量而不是解析器实现。

于 2012-04-26T04:54:46.700 回答