Go的encoding/xml包要求结构体字段必须导出并正确使用xml标签:非导出字段被忽略;未加tag按字段名大小写敏感匹配;xml:"name"指定元素名,xml:",attr"绑定属性,xml:",chardata"捕获文本,空标签用*bool或omitempty控制,重复元素须用slice接收,嵌套需严格对应,xml:",any"捕获未知子元素,序列化时零值或nil需omitempty才省略,CDATA和命名空间需手动处理,尤其默认命名空间必须显式写出URI。

Go 的 encoding/xml 包能直接将结构体和 XML 互转,但字段标签、嵌套规则、命名空间稍不注意就会反序列化失败或丢失数据。
XML 反序列化时 struct 字段必须导出且带正确 tag
非导出字段(小写开头)会被忽略;没加 xml tag 的字段默认按字段名匹配 XML 元素名,大小写敏感且不处理下划线/驼峰转换。
- 用
xml:"name"显式指定元素名,例如xml:"user_name"对应Alice - 用
xml:",attr"绑定属性,如ID int `xml:"id,attr"`解析 - 用
xml:",chardata"捕获文本内容,适用于中的 "Bob"Bob - 空 tag 如
建议用*bool或bool+xml:",omitempty"控制是否忽略
嵌套结构与 slice 的 XML 解析容易漏掉数据
XML 中重复出现的同名元素(如多个 )必须用 slice 接收,否则只取第一个;嵌套层级需严格对应 struct 嵌套,匿名字段不会自动展开。
- 错误写法:
Items Item `xml:"item"`→ 只解析第一个 - 正确写法:
Items []Item `xml:"item"` - 若 XML 是
,struct 需写成- ...
Items struct { Item []Item `xml:"item"` } `xml:"items"`或直接内嵌Items []Item `xml:"items>item"` - 用
xml:",any"可捕获未知子元素,但需自行解析其XMLName.Local和内容
XML 序列化时 nil 指针和零值字段默认仍会输出
xml.Marshal 不会跳过 nil 指针字段,也不会因字段为零值(0、""、false)而省略——除非显式加 omitempty。
立即学习“go语言免费学习笔记(深入)”;
-
Name string `xml:"name,omitempty"`:当Name == ""时不生成 -
Active *bool `xml:"active,omitempty"`:当Active == nil时不输出该元素 -
omitempty对 struct 字段有效,但对 map 或 interface{} 无效 - 若需完全控制输出逻辑,可实现
MarshalXML方法,但要注意避免无限递归调用xml.Marshal
特殊字符、CDATA 和命名空间需手动处理
encoding/xml 默认把 、> 等转义为实体,不支持原生 CDATA;命名空间前缀(如 ns:tag)需靠 XMLName.Space 和自定义命名空间声明配合。
- 要输出 CDATA,得在
MarshalXML里手动写入字符串,不能依赖 tag - 带命名空间的 XML(如
),需在顶层 struct 设XMLName xml.Name `xml:"rss"`,并在字段 tag 中写xml:"dc:title",同时确保dc前缀已在 XML 声明中存在 - 解析含默认命名空间(
xmlns="...")的文档时,所有元素都属于该空间,struct 字段 tag 必须带完整空间名,例如xml:"http://example.com title"
最常被忽略的是默认命名空间的处理——它不像前缀命名空间那样能靠 tag 名字隐式识别,必须显式写出 URI 字符串,否则字段永远匹配不上。










