将XML文件拆分为多个文件

时间:2014-06-10 06:47:16

标签: groovy

假设我有以下XML文件:

<a>
  <b>
   ....
  </b>
  <b>
   ....
  </b>
  <b>
   ....
  </b>
</a>

我希望根据<b>标记的数量将此文件拆分为多个XML文件。

像:

File01.xml

<a>
  <b>
   ....
  </b>
</a>

File02.xml

<a>
  <b>
   ....
  </b>
</a>

File03.xml

<a>
  <b>
   ....
  </b>
</a>

等等......

我是Groovy的新手,我尝试使用以下代码。

import java.util.HashMap
import java.util.List
import javax.xml.parsers.DocumentBuilderFactory
import org.custommonkey.xmlunit.*
import org.w3c.dom.NodeList
import javax.xml.xpath.*
import javax.xml.transform.TransformerFactory
import org.w3c.dom.*
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult

class file_split {   

        File input = new File("C:\\file\\input.xml")
        def dbf  = DocumentBuilderFactory.newInstance().newDocumentBuilder()
        def doc = new XmlSlurper(dbf).parse(ClassLoader.getSystemResourceAsStream(input));
        def xpath = XPathFactory.newInstance().newXPath()

        NodeList nodes = (NodeList) xpath.evaluate("//a/b", doc, XPathConstants.NODESET)

        def itemsPerFile = 5;
        def fileNumber = 0;

        def currentdoc = dbf.newDocument()
        def rootNode = currentdoc.createElement("a")
        def currentFile = new File(fileNumber + ".xml")

        try{
            for(i = 1; i <= nodes.getLength(); i++){
                def imported = currentdoc.importNode(nodes.item(i-1), true)
                rootNode.appendChild(imported)

                if(i % itemsPerFile == 0){
                    writeToFile(rootNode, currentFile)

                    rootNode = currentdoc.createElement("a");
                    currentFile = new File((++fileNumber)+".xml");
                }
            }
        }
        catch(Exception ex){
            logError(file.name,ex.getMessage());
            ex.printStackTrace();
        }

    def writeToFile(Node node, File file) throws Exception {
        def transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(new DOMSource(node), new StreamResult(new FileWriter(file)));
    }
}

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

这应该有效:

import groovy.xml.*

new XmlSlurper().parseText( file ).b.eachWithIndex { element, index ->
    new File( "/tmp/File${ "${index+1}".padLeft( 2, '0' ) }.xml" ).withWriter { w ->
        w << XmlUtil.serialize( new StreamingMarkupBuilder().bind {
            a { 
                mkp.yield element
            }
        } )
    }
}

如果要对它们进行分组,可以使用整理(此示例为每个文件分组2 b个标记:

import groovy.xml.*

new XmlSlurper().parseText( file )
                .b
                .toList()
                .collate( 2 )
                .eachWithIndex { elements, index ->
    new File( "/tmp/File${ "${index+1}".padLeft( 2, '0' ) }.txt" ).withWriter { w ->
        w << XmlUtil.serialize( new StreamingMarkupBuilder().bind {
            a {
                elements.each { element ->
                    mkp.yield element
                }
            }
        } )
    }
}

答案 1 :(得分:0)

我不知道您遇到了什么问题,但似乎您需要时创建新的rootNode,而不是新的currentdoc。在重新初始化循环中的currentdoc之前,请尝试重新初始化rootNode