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

如何配置Apache Xalan-Transformer避免生成空行?

解决Xalan XML转换器重复格式化时生成大量空行的问题

问题现象

使用Xalan转换器对XML进行缩进格式化时,首次处理无缩进的XML(如:

<foo><bar/></foo>

)会得到符合预期的格式化结果:

<?xml version="1.0" encoding="UTF-8"?><foo>
    <bar/>
</foo>

但再次对该格式化后的XML进行转换时,会生成大量空行:

<?xml version="1.0" encoding="UTF-8"?><foo>
        
    <bar/>
    
</foo>

且每次重复转换,空行数量都会持续增加。而Saxon转换器不存在此问题。

问题原因

Xalan默认的XML格式化逻辑不会移除输入XML中的空白文本节点,每次转换都会在原有空白的基础上叠加新的缩进空白,导致空行累积。

解决方法

通过自定义XSLT样式表,先剥离XML中不必要的空白节点,再执行缩进格式化,确保重复处理时结果一致。

步骤1:定义XSLT样式表

创建一个用于清理空白并格式化XML的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 剥离所有元素的空白文本节点 -->
    <xsl:strip-space elements="*"/>
    <!-- 开启XML缩进输出 -->
    <xsl:output method="xml" indent="yes"/>
    <!-- 复制所有节点和属性 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

步骤2:修改测试代码

使用上述XSLT创建Transformer,替换默认的Transformer实例:

import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.junit.Assert;
import org.junit.jupiter.api.Test;

class TransformerTest {
    @Test
    void formattingShouldBeIdempotent() throws Exception
    {
      // 定义XSLT样式表字符串
      String xslt = """
          <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
              <xsl:strip-space elements="*"/>
              <xsl:output method="xml" indent="yes"/>
              <xsl:template match="@*|node()">
                  <xsl:copy>
                      <xsl:apply-templates select="@*|node()"/>
                  </xsl:copy>
              </xsl:template>
          </xsl:stylesheet>
          """;

      TransformerFactory factory = TransformerFactory.newDefaultInstance();
      // 使用XSLT创建Transformer
      Transformer transformer = factory.newTransformer(new StreamSource(new StringReader(xslt)));

      String transformed1 = transform("<foo><bar/></foo>", transformer);
      String transformed2 = transform(transformed1, transformer);

      Assert.assertEquals(transformed1, transformed2);
    }

    private String transform(String input, Transformer transformer) throws TransformerException
    {
      Source source = new StreamSource(new StringReader(input));
      StringWriter outWriter = new StringWriter();
      StreamResult result = new StreamResult(outWriter);
      transformer.transform(source, result);
      return outWriter.getBuffer().toString();
    }
}

原理说明

  • <xsl:strip-space elements="*"/> 会移除所有元素中的空白文本节点,避免原有空白影响后续格式化。
  • <xsl:output method="xml" indent="yes"/> 开启缩进输出,确保生成格式规范的XML。
  • 模板匹配逻辑会完整复制原XML的所有节点和属性,仅处理空白和格式化,不改变XML的业务内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:07:07