使用jaxp分割xml文件

前言:

将一个大的xml文件分割成若干个小的xml文件,同事使用python实现过,最近学习java,以此练手使用java的jaxp包实现该功能!

xml文件( 如下 )中datas节点的子节点data有若干个,当超出100个的时候,就需要以data节点分割成若干份小的xml文件

<?xml version="1.0" encoding="utf-8" ?>
    <head>....</head>
    <datas>
        <data>...</data>
        <data>...</data>
        <data>...</data>
        <!--若干个data节点-->
    </datas>
</root>

1.获取datas节点的子节点data集合;
2.复制该data节点集合(没有找到相关的复制方法,这里通过遍历data集合将data元素存储到ArrayLisrt中);
3.判断data集合长度,若超过了阈值,则进行分割;
4.每次分割前都需要清除datas节点,并重新创建创建,保证分割的数据准确性;
5.保存分割的xml文件

分割xml的代码(核心):
    //分割文件:当data大于100的时候,将其分割成data小于100的xml
    public static void splitXML(Document document, ArrayList<Node> copyNodeList) {
        // 添加data节点到datas节点下
        int nodesLen = copyNodeList.size();
        // 分割的组数:计算可以分成多少组
        int splitTimes = (int) Math.ceil((double) nodesLen / splitSize);
        if (nodesLen >= splitSize) {
            // 外层循环:控制文件分割的次数
            for (int i = 0; i < splitTimes; i++) {
                // 获取datas节点
                Node datasNode = document.getElementsByTagName("datas").item(0);
                // 获取datas节点的父节点
                Node parentDatasNode = datasNode.getParentNode();
                // 清空datas节点,这样就清空了datas节点的所有内容
                parentDatasNode.removeChild(datasNode);
                // 创建datas节点
                Element newDatasNode = document.createElement("datas");
                // 开始位置
                int fromIndex = i * splitSize;
                // 结束位置:通过三目运算符获取结束值
                int toIndex = (i + 1) * splitSize < nodesLen ? (i + 1) * splitSize : nodesLen;
                System.out.println("fromIndex:" + fromIndex + ":toIndex:" + toIndex);
                for (int j = fromIndex; j < toIndex; j++) {
                    newDatasNode.appendChild(copyNodeList.get(j));
                // 添加datas节点到父节点上
                parentDatasNode.appendChild(newDatasNode);
                // 文件的回写
                writeXML(document, saveXmlFolder);
完整代码:
使用jaxp操作xml文件 import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.io.*; import java.util.ArrayList; import java.util.UUID; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; public class SplitXMLFile { // 文件分割的大小 private static int splitSize = 100; private static String xmlFolder = "src_xml_path.xml"; private static String saveXmlFolder = "split.xml"; public static void main(String[] args) throws Exception { // 获取根节点 Document nodeRoot = getRootNode(); //通过根节点,获取data节点集合,并复制 ArrayList<Node> copyNodeList = getDataList(nodeRoot); // 分割文件:大文件分割为小文件 splitXML(nodeRoot, copyNodeList); // 复制datas节点,为了拿到data数据集合 public static ArrayList<Node> copyDataList(NodeList nodeList) { ArrayList<Node> arrayList = new ArrayList<>(); for (int i = 0; i < nodeList.getLength(); i++) { arrayList.add(nodeList.item(i)); return arrayList; //分割文件:当data大于100的时候,将其分割成data小于100的xml public static void splitXML(Document document, ArrayList<Node> copyNodeList) { // 添加data节点到datas节点下 int nodesLen = copyNodeList.size(); // 分割的组数:计算可以分成多少组 int splitTimes = (int) Math.ceil((double) nodesLen / splitSize); if (nodesLen >= splitSize) { // 外层循环:控制文件分割的次数 for (int i = 0; i < splitTimes; i++) { // 获取datas节点 Node datasNode = document.getElementsByTagName("datas").item(0); // 获取datas节点的父节点 Node parentDatasNode = datasNode.getParentNode(); // 清空datas节点,这样就清空了datas节点的所有内容 parentDatasNode.removeChild(datasNode); // 创建datas节点 Element newDatasNode = document.createElement("datas"); // 开始位置 int fromIndex = i * splitSize; // 结束位置:通过三目运算符获取结束值 int toIndex = (i + 1) * splitSize < nodesLen ? (i + 1) * splitSize : nodesLen; System.out.println("fromIndex:" + fromIndex + ":toIndex:" + toIndex); for (int j = fromIndex; j < toIndex; j++) { newDatasNode.appendChild(copyNodeList.get(j)); // 添加datas节点到父节点上 parentDatasNode.appendChild(newDatasNode); // 文件的回写 writeXML(document, saveXmlFolder); //回写添加的节点文件 public static void writeXML(Node document, String xmlPath) { String[] pathLst = xmlPath.split("\\."); StringBuffer sb = new StringBuffer(); sb.append(pathLst[0]).append("_" + UUID.randomUUID()).append("." + pathLst[1]); // 分割为小文件的xml文件路径 String splitXmlPath = sb.toString(); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer; try { transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult(splitXmlPath)); } catch (Exception e) { e.printStackTrace(); try { // 读取数据 StringBuffer splitXmlSb = new StringBuffer(); BufferedReader br = new BufferedReader(new FileReader(splitXmlPath)); String line; while ((line = br.readLine()) != null) { splitXmlSb.append(line); br.close(); //写入数据 BufferedWriter bw = new BufferedWriter(new FileWriter(splitXmlPath)); String xmlContent = splitXmlSb.toString().replaceAll("\r|\n", ""); bw.write(xmlContent); bw.newLine(); bw.flush(); bw.close(); } catch (IOException e) { e.printStackTrace(); // 获取节点的data数据集合 public static ArrayList<Node> getDataList(Document document) { NodeList nodeList = document.getElementsByTagName("data"); //复制datas节点,为了拿到data数据集合 return copyDataList(nodeList); // 获取xml文件的根节点 public static Document getRootNode() throws Exception { //创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); // 解析:得到文档对象 Document document = builder.parse(xmlFolder); return document;