ctx.ReadXML() 是唯一安全的 XML 请求读取方式,它内部缓冲重放并校验 Content-Type;结构体字段须导出且 xml tag 精确匹配元素名,含命名空间需显式声明;ctx.XML() 输出自动设 ContentType 并序列化,勿拼字符串;多格式需手动解析 Accept 头分支处理。

ctx.ReadXML() 是唯一安全的 XML 请求读取方式
别自己 io.ReadAll(ctx.Request().Body) 再调 xml.Unmarshal——这会让后续中间件或 handler 读到空 body,因为 HTTP body 是一次性流。Iris 的 ctx.ReadXML(&v) 内部已做缓冲和重放处理,且自动校验 Content-Type 是否为 application/xml 或 text/xml;不匹配直接返回 415 错误。
结构体字段必须导出(首字母大写),且 tag 要精确匹配 XML 元素名:
-
xml:"name"对应<name>Alice</name> - 含命名空间时,如
<user xmlns="http://api.example.com"></user>,需写xml:"user" xmlns:"http://api.example.com" - 根元素名不一致?用
XMLName xml.Name `xml:"response"`显式声明
ctx.XML() 输出时注意 omitempty 和缩进
用 ctx.XML(v, iris.XML{Indent: true}) 输出,Iris 会自动设 Content-Type: application/xml; charset=UTF-8 并调 xml.Marshal()。不要拼字符串或用 ctx.WriteString(),易出编码/转义问题。
- 字段值为 nil 指针或空切片时,默认序列化成
<items></items>;加xml:",omitempty"可跳过该字段 -
iris.XML{Indent: true}仅用于调试,生产环境务必设为false - 中文无需额外处理,
xml.Marshal()默认 UTF-8 编码
XML 和 JSON 共存时 Content-Type 不自动协商
Iris 不会根据 Accept 头自动选择序列化方式。你显式调 ctx.JSON() 就走 JSON 路径,调 ctx.XML() 就走 XML 路径——哪怕客户端 Accept 里写了 application/xml,handler 里没调 ctx.XML(),照样不会输出 XML。
- 同一个接口想支持多格式?得自己解析
ctx.GetHeader("Accept"),再分支调用对应方法 - 别指望中间件统一拦截并“自动转”,Iris 没这层协议感知能力
- POST 请求体类型由
Content-Type决定,不是Accept;两者职责完全不同
结构体设计要干净,别混数据库字段
XML 请求模型不是 GORM 模型。别在 struct 里塞 gorm.Model、sql.NullString 或 json:",omitempty" 这类跨层语义标签。它只负责承载一次 HTTP 交互的数据契约。
- 字段名用 Go 小写风格,JSON/XML tag 显式声明,避免依赖默认驼峰转换
- 嵌套结构体可直接映射 XML 子节点,但注意每个子字段仍需导出 + 正确 tag
- 如果 XML 含混合内容(如
<p>Hello <em>world</em></p>),用xml:",chardata"或xml:",any"捕获原始文本
ctx.ReadXML() 自带 Content-Type 校验——这三个点卡住的人最多。


















