transformer需显式设置outputkeys.indent="yes"和"{http://xml.apache.org/xslt}indent-amount"才能启用缩进,但更推荐使用lsserializer的format-pretty-print参数实现稳定格式化。

Java 中的 Transformer(来自 javax.xml.transform)本身不直接控制“输出格式化”(如缩进、换行、空格),但可以通过设置 OutputKeys 属性来影响 XML 输出的可读性。关键在于配置 Transformer 的输出属性,尤其是启用缩进(indentation)并指定缩进量。
启用缩进并设置缩进宽度
默认情况下,Transformer 输出是紧凑型(无换行、无缩进)。要获得格式化输出,需显式设置以下两个属性:
-
OutputKeys.INDENT设为"yes"(启用缩进) -
"{http://xml.apache.org/xslt}indent-amount"设为整数(如"2"),指定每级缩进的空格数(注意:这是 Xalan 特有属性,非标准,但被主流 JDK 内置 XSLT 实现支持)
使用 DOMSource + StreamResult 的典型配置示例
以下代码将生成带缩进的 XML 输出:
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 可选
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
注意事项与兼容性提示
不同 JDK 版本或底层 XSLT 引擎(如 Xalan vs. JDK 自带的 TrAX 实现)对缩进的支持略有差异:
立即学习“Java免费学习笔记(深入)”;
- JDK 8 及以后版本内置实现基本支持
indent-amount,但若遇到无效缩进,可尝试升级到较新 JDK 或显式引入xalan:xalan依赖 -
OutputKeys.INDENT设为"yes"并不保证所有节点都自动换行——它依赖于源 DOM 树中是否保留原始空白(即DocumentBuilder.setIgnoringElementContentWhitespace(false)),且对已压缩的 DOM 可能效果有限 - 若需更精细控制(如强制换行、自定义换行符),建议改用
javax.xml.parsers.DocumentBuilder配合org.w3c.dom.ls.LSSerializer(DOM Level 3 LS API),它提供format-pretty-print等更可靠选项
替代方案:使用 LSSerializer(推荐用于纯格式化需求)
当目标只是美化已有 DOM 输出,而非执行 XSLT 转换时,LSSerializer 更稳定、语义更清晰:
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementation domImpl = registry.getDOMImplementation("LS");
LSSerializer serializer = ((DOMImplementationLS) domImpl).createLSSerializer();
serializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
String xmlString = serializer.writeToString(document);
不复杂但容易忽略:缩进不是 Transformer 的默认行为,必须主动开启并配对设置 indent-amount;对格式要求高的场景,优先考虑 LSSerializer。










