XML转换过程中,源文档的空白字符(如换行、制表符、连续空格)和排版格式很容易因为解析器、转换规则的默认处理而丢失,要保留这些内容需要从解析、转换、输出三个环节做针对性配置。

空白和格式丢失的常见原因
大部分XML解析器默认会忽略纯空白的文本节点,或者在解析时对连续空白做归一化处理,这是导致格式丢失的核心原因。另外XSLT转换的默认规则也会对文本节点做trim处理,进一步破坏原有格式。
解析器的默认行为
比如DOM解析器在加载XML时,如果开启了忽略空白节点的配置,会自动删除元素之间仅包含空白的文本节点,导致原有的换行、缩进排版消失。
转换规则的默认处理
XSLT转换中,<xsl:output>的默认设置不会对空白做特殊处理,同时模板匹配时如果没有显式保留空白,转换后的输出会丢失源文档的排版。
不同场景下的保留方法
使用DOM解析时保留空白
在Java中使用DOM解析XML时,需要关闭忽略空白节点的配置,同时开启保留格式的开关,示例代码如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class XmlParseDemo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 关闭忽略空白节点的配置,保留源文档中的空白文本节点
factory.setIgnoringElementContentWhitespace(false);
// 开启命名空间感知,避免格式解析异常
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析源XML文档
Document doc = builder.parse("source.xml");
// 后续可以对doc进行转换操作,空白已经被保留
}
}
XSLT转换时保留空白和格式
在使用XSLT做XML转换时,需要在XSLT文件中做两项配置:一是设置<xsl:output>的indent属性为yes,同时开启保留空白的配置;二是在模板中显式匹配空白文本节点并保留。
首先是对应的XSLT文件示例:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 输出配置:开启缩进,编码为UTF-8 -->
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<!-- 保留所有空白文本节点 -->
<xsl:preserve-space elements="*"/>
<!-- 根模板,复制所有节点 -->
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- 复制节点的通用模板 -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
然后是调用XSLT做转换的Java代码示例:
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
public class XsltTransformDemo {
public static void main(String[] args) throws Exception {
TransformerFactory factory = TransformerFactory.newInstance();
// 加载XSLT文件
Transformer transformer = factory.newTransformer(new StreamSource(new File("transform.xsl")));
// 设置转换参数,确保空白不被修剪
transformer.setOutputProperty("omit-xml-declaration", "no");
// 执行转换,输入源XML,输出转换后的文件
transformer.transform(new StreamSource(new File("source.xml")), new StreamResult(new File("result.xml")));
}
}
使用Python进行XML转换时保留格式
Python的lxml库在解析和转换XML时,可以通过参数控制空白的保留,示例代码如下:
from lxml import etree
# 解析源XML时,设置remove_blank_text为False,保留空白节点
parser = etree.XMLParser(remove_blank_text=False)
tree = etree.parse("source.xml", parser)
# 加载XSLT转换规则
xslt_tree = etree.parse("transform.xsl")
transform = etree.XSLT(xslt_tree)
# 执行转换
result_tree = transform(tree)
# 输出转换结果,设置pretty_print为True保留缩进格式
result_tree.write("result.xml", pretty_print=True, encoding="UTF-8")
注意事项
- 如果源XML文档本身没有规范的缩进格式,即使开启了保留配置,转换后的文档也不会自动生成排版,只会保留原有的空白内容。
- 部分XML编辑器会自动对文档做格式化处理,如果你发现源文档的格式在转换前就丢失了,需要先确认源文档的原始内容是否包含对应的空白字符。
- 如果转换后需要和源文档完全一致,除了保留空白,还要确保转换规则中没有删除或新增额外的空白文本节点,最好使用节点复制的方式做转换。
保留空白和格式会增加XML文档的体积,如果转换后的文档仅用于程序解析,不需要人工阅读,可以不需要刻意保留格式,减少存储和传输开销。
XML转换空白保留格式保留xml_stylesheet修改时间:2026-06-22 02:24:35