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

使用Xalan进行XSLT转换时Emoji编码异常问题求助

XSLT中Xalan转换器处理Emoji编码异常的解决方案

问题背景

用XSLT生成HTML时碰到Emoji处理异常,测试不同转换引擎的表现:

  • Saxon转换器:能正确输出Emoji
  • Java内置Xalan转换器(com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl):textarea里的Emoji显示正常,但input标签的value属性中Emoji编码错误
  • Xalan 2.7.2:问题更严重

因许可证限制,优先用Xalan转换器,需要解决Emoji的正确处理问题。

测试代码

Java转换代码

TransformerFactory factory = TransformerFactory.newInstance(
        "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl",
        null);
Transformer transformer = factory.newTransformer(new StreamSource(xsl));
DocumentSource domSource = new DocumentSource(doc);
OutputStream stream = response.getOutputStream();

transformer.transform(domSource, new StreamResult(stream));

stream.flush();
stream.close();

(注:doc为dom4j文档,xsl为测试样式表输入流,response为HttpServletResponse对象)

测试用XSL样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" encoding="UTF-8"/>
  <xsl:template match="/">
    <xsl:text disable-output-escaping="yes">&lt;!doctype html&gt;</xsl:text>
    <html>
      <head>
        <meta charset="UTF-8"/>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      </head>
      <body>
        <textarea>👍🏻</textarea><br/>
        <input type="text" value="👍🏻"/>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

解决方法

1. 显式设置响应编码

除了XSL中指定<xsl:output encoding="UTF-8"/>,还要给HttpServletResponse明确设置编码,避免容器默认编码干扰:

// 在获取输出流前添加这两行
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");

OutputStream stream = response.getOutputStream();

2. 调整XSL中属性的写法

Xalan处理HTML属性时的转义逻辑可能有问题,改用xsl:attribute来定义input的value属性,避免直接写在标签内:

<!-- 替换原input标签 -->
<input type="text">
  <xsl:attribute name="value">👍🏻</xsl:attribute>
</input>

如果还是有问题,可以尝试禁用属性值的输出转义(注意仅在确认内容安全时使用):

<input type="text">
  <xsl:attribute name="value">
    <xsl:text disable-output-escaping="yes">👍🏻</xsl:text>
  </xsl:attribute>
</input>

3. 升级Xalan版本

Xalan 2.7.2存在字符编码相关bug,升级到2.7.3及以上版本(需确认许可证符合要求),部分后续版本修复了UTF-8多字节字符在属性中的转义问题。

4. 转换dom4j文档的输入方式

直接用dom4j文档生成DOMSource可能导致字符编码丢失,先把dom4j文档序列化为UTF-8编码的XML流,再用StreamSource传入转换器:

// 将dom4j文档转为UTF-8字节流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(baos, format);
writer.write(doc);

// 使用StreamSource代替DocumentSource
StreamSource source = new StreamSource(new ByteArrayInputStream(baos.toByteArray()));
transformer.transform(source, new StreamResult(stream));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:31:50