
XMLStreamWriter.writeCharacters() 方法会自动处理 XML 特殊字符(如 , &, ", ')的转义,因此在调用前对字符串执行 StringEscapeUtils.escapeXml() 会导致重复转义(例如 & 变成 &),破坏原始语义。正确做法是直接传入原始字符串,交由 StAX API 安全处理。
xmlstreamwriter 写入文本时无需手动转义字符
在使用 Java 的 StAX(Streaming API for XML)进行 XML 生成时,一个常见误区是:在调用 XMLStreamWriter.writeCharacters(String) 前,先用工具类(如 StringEscapeUtils.escapeXml())对字符串做预转义。这不仅多余,而且会导致严重问题 —— 比如德语字符 ü 的 Unicode 实体 ü 中的 & 会被二次转义为 ü,最终 XML 解析器无法还原为原字符。
实际上,XMLStreamWriter 的设计原则是「安全即默认」:它会在写入文本内容时自动识别并转义所有需要被 XML 规范编码的字符,包括:
→ <code>(必须转义)-
>→>(可选,但多数实现会转义) -
&→&(必须转义) -
"→"(在属性值中必须,在文本内容中可选但通常执行) -
'→'(同上)
✅ 正确用法(推荐):
writer.writeStartElement("name");
writer.writeCharacters("Begünstigter"); // 直接传入原始字符串
writer.writeEndElement();输出结果(符合 XML 标准):
<name>Begünstigter</name>
❌ 错误用法(导致双重转义):
writer.writeCharacters(StringEscapeUtils.escapeXml("Begünstigter"));
// 输出:Begünstigter ← XML 解析器将显示为 "Begünstigter"(文字而非 ü)⚠️ 注意事项:
- 不要混合使用手动转义与
writeCharacters();若已用StringEscapeUtils处理过,应改用writeRaw()(不推荐,绕过安全机制,易引入 XML 注入风险)。 - 若需写入 CDATA 区段(如含大量
或 <code>&的富文本),可显式使用:writer.writeCData("Content with <tags> & entities"); - 确保
XMLStreamWriter实例来自标准 JAXP 实现(如 Woodstox 或 JDK 自带),其writeCharacters()行为均符合 W3C XML 1.0 规范。
? 修复你原始代码只需一行改动:
// ❌ 错误(删除这一行转义) // writer.writeCharacters(StringEscapeUtils.escapeXml(entry.getValue().toString())); // ✅ 正确:直接写入原始字符串 writer.writeCharacters(entry.getValue().toString());
总结:StAX 的 XMLStreamWriter 是智能且安全的 —— 把转义交给它,你只负责提供原始语义数据。这是避免乱码、实体嵌套、解析失败等问题最简单也最可靠的实践。


















