假设我有以下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)));
}
}
非常感谢任何帮助。
答案 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
。