XMLStreamWriter 默认不生成 XML 声明,必须显式调用 writeStartDocument();需正确配对 writeStartElement/writeEndElement;编码须统一,推荐用 createXMLStreamWriter(OutputStream, encoding) 避免双重编码。

XMLStreamWriter 写 XML 时为什么没生成声明?
默认情况下 XMLStreamWriter 不会自动写入 XML 声明(),必须显式调用 writeStartDocument()。漏掉这步,生成的文件可能被某些解析器拒绝或乱码。
-
writeStartDocument():写入完整声明,含编码(推荐) -
writeStartDocument(String encoding):指定编码,如"UTF-8" -
writeStartDocument(String version, String encoding):同时控制版本与编码 - 不调用该方法 → 输出从根元素开始,无声明
如何正确创建和关闭 XMLStreamWriter?
不能只靠 close(),必须确保 flush() 和 close() 都执行,否则缓冲区内容可能丢失。常见错误是 try-with-resources 用错对象 —— 要包装的是 XMLStreamWriter 本身,不是底层的 OutputStream 或 Writer。
XMLOutputFactory factory = XMLOutputFactory.newInstance();
try (XMLStreamWriter writer = factory.createXMLStreamWriter(new FileOutputStream("out.xml"), "UTF-8")) {
writer.writeStartDocument("UTF-8"); // 必须
writer.writeStartElement("root");
writer.writeStartElement("item");
writer.writeAttribute("id", "1");
writer.writeCharacters("hello");
writer.writeEndElement();
writer.writeEndElement();
writer.writeEndDocument();
writer.flush(); // 显式刷出缓冲区
}
writeStartElement 和 writeEndElement 容易配对错误吗?
是的,XMLStreamWriter 不做嵌套校验,写错层级会导致 XML 格式非法。没有自动“补全”机制,所有 writeStartElement() 都必须有对应 writeEndElement(),且顺序严格匹配。
- 嵌套过深时建议用栈记录元素名,或借助工具类封装 begin/end
- 不要在循环中只写 start 忘记 end,尤其处理集合时
-
writeEmptyElement("tag")可替代 start+end 组合写空标签(如) - 写属性必须在对应
writeStartElement()之后、子内容之前
中文乱码或特殊字符报错怎么处理?
根本原因是编码不一致:writeStartDocument() 指定的编码必须与输出流/Writer 实际使用的编码一致。若用 FileOutputStream + 字符串编码参数,底层仍走字节流,需确保构造时未额外用 OutputStreamWriter 包裹(会重复编码)。
立即学习“Java免费学习笔记(深入)”;
- 推荐方式:用
factory.createXMLStreamWriter(OutputStream, encoding),由 StAX 自行处理编码 - 避免:先 new
OutputStreamWriter(out, "UTF-8")再传给createXMLStreamWriter()→ 双重编码,中文变乱码 - 特殊字符如
&、会自动转义,无需手动替换;但 CDATA 块需用writeCData() - 如果抛
XMLStreamException: Invalid character,检查是否往文本内容里写了未转义的控制字符(如 \u0000)










