You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java保存XML文件时元素间重复新增空白行的解决方法

解决Java保存XML多次运行后元素间逐次新增空白行的问题

问题原因

DOM解析器会将XML文件中的空白字符(换行、缩进空格)解析为文本节点,每次保存时,由于开启了Transformer的缩进配置(INDENT="yes"),会再次生成新的缩进空白,原有的空白文本节点被保留,叠加后就出现了元素间逐次新增空白行的现象。

解决方案

方法1:解析XML时忽略空白节点

修改DocumentBuilderFactory的配置,从根源避免空白文本节点被加入DOM树:

public static void main(String[] args) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    // 开启忽略空白节点,需同时开启命名空间支持才生效
    factory.setIgnoringElementContentWhitespace(true);
    factory.setNamespaceAware(true);
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse("src/main/resources/chunkInfo/chunk.xml");
        add(document);
        saveDocument(document, new File("src/main/resources/chunkInfo/chunk.xml"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

方法2:保存前清理DOM树中的空白文本节点

如果不想修改解析逻辑,可以在保存前手动遍历DOM树,删除空文本节点:
首先添加清理空白的工具方法:

public static void removeWhitespaceNodes(Node node) {
    NodeList children = node.getChildNodes();
    // 倒序遍历避免删除节点后索引错乱
    for (int i = children.getLength() - 1; i >= 0; i--) {
        Node child = children.item(i);
        // 删除仅包含空白字符的文本节点
        if (child.getNodeType() == Node.TEXT_NODE && child.getTextContent().trim().isEmpty()) {
            node.removeChild(child);
        } else if (child.getNodeType() == Node.ELEMENT_NODE) {
            // 递归清理子元素
            removeWhitespaceNodes(child);
        }
    }
}

然后在保存前调用该方法:

public static void main(String[] args) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse("src/main/resources/chunkInfo/chunk.xml");
        add(document);
        // 清理空白节点后再保存
        removeWhitespaceNodes(document.getDocumentElement());
        saveDocument(document, new File("src/main/resources/chunkInfo/chunk.xml"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

方法3:优化Transformer缩进配置(辅助)

部分Transformer实现对indent-number属性支持不佳,可以替换为XSLT标准缩进属性,配合前两种方法使用:

public static void saveDocument(Document document, File xmlFile) {
    TransformerFactory tff = TransformerFactory.newInstance();
    try {
        Transformer tf = tff.newTransformer();
        tf.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "chunk.dtd");
        tf.setOutputProperty(OutputKeys.INDENT, "yes");
        // 使用XSLT的缩进属性替代indent-number
        tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        tf.transform(new DOMSource(document), new StreamResult(xmlFile));
    } catch (TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    }
}

验证效果

修改后多次运行程序,XML文件中元素间的空白行不会再逐次新增,新插入的元素格式保持一致。

内容的提问来源于stack exchange,提问作者miniWorld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:01:17