使用Java拆分1GB Xml文件

时间:2011-03-02 15:53:10

标签: java xml

我有一个1GB的Xml文件,如何使用Java将其拆分为格式正确的小型Xml文件?

以下是一个例子:

<records>
  <record id="001">
    <name>john</name>
  </record>
 ....
</records>

感谢。

4 个答案:

答案 0 :(得分:18)

我会在这种情况下使用StAX解析器。它将阻止整个文档一次被读入内存。

  1. 将XMLStreamReader推进到子片段的本地根元素。
  2. 然后,您可以使用javax.xml.transform API从此XML片段生成新文档。这会将XMLStreamReader推进到该片段的末尾。
  3. 对下一个片段重复步骤1.
  4. 代码示例

    对于以下XML,将每个“statement”部分输出到以“account attributes value”命名的文件中:

    <statements>
       <statement account="123">
          ...stuff...
       </statement>
       <statement account="456">
          ...stuff...
       </statement>
    </statements>
    

    可以使用以下代码完成此操作:

    import java.io.File;
    import java.io.FileReader;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLStreamConstants;
    import javax.xml.stream.XMLStreamReader;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stax.StAXSource;
    import javax.xml.transform.stream.StreamResult;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception  {
            XMLInputFactory xif = XMLInputFactory.newInstance();
            XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml"));
            xsr.nextTag(); // Advance to statements element
    
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
                File file = new File("out/" + xsr.getAttributeValue(null, "account") + ".xml");
                t.transform(new StAXSource(xsr), new StreamResult(file));
            }
        }
    
    } 
    

答案 1 :(得分:3)

尝试使用Saxon-EE 9.3。

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:mode streamable="yes"/>
    <xsl:template match="record">
      <xsl:result-document href="record-{@id}.xml">
        <xsl:copy-of select="."/>
      </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

该软件是免费的,但如果它为您节省了一天的编码,您可以轻松证明投资的合理性。 (对销售宣传道歉)。

答案 2 :(得分:2)

DOM,STax,SAX都会做,但有自己的优点和缺点。

  1. 如果是DOM,则无法将所有数据存入内存。
  2. 对于DOM,然后是Stax,然后是SAX,编程控制更容易。
  3. SAX和DOM的组合是更好的选择。
  4. 使用已经执行此操作的框架可能是最佳选择。看看smooks。http://www.smooks.org
  5. 希望这有帮助

答案 3 :(得分:1)

我恭敬地不同意Blaise Doughan。 SAX不仅难以使用,而且非常慢。使用VTD-XML,您不仅可以使用XPath来简化处理逻辑(10倍代码减少非常常见),而且还可以更快,因为没有冗余编码/解码转换。下面是带有vtd-xml的java代码

import java.io.FileOutputStream;
import com.ximpleware.*; 

public class split {
    public static void main(String[] args) throws Exception {       
        VTDGen vg = new VTDGen();       
        if (vg.parseHttpUrl("c:\\xml\\input.xml", true)) {
            VTDNav vn = vg.getNav();
            AutoPilot ap = new AutoPilot(vn);
            ap.selectXPath("/records/record");
            int i=-1,j=0;
            while ((i = ap.evalXPath()) != -1) {
            long l=vn.getElementFragment();
                (new FileOutputStream("out"+j+".xml")).write(vn.getXML().getBytes(), (int)l,(int)(l>>32));
                j++;
            }
        }
    }
}