Go的xml.Unmarshal要求结构体字段首字母大写且用xml标签映射,属性需加,attr,纯文本内容需用,chardata,根节点须匹配或直接解析为字符串。

结构体字段必须首字母大写,否则解析结果为空
Go 的 xml.Unmarshal 依赖反射访问字段,而反射只能操作导出字段(即首字母大写的字段)。哪怕 XML 标签名是小写(比如 ),结构体字段也得写成 Title,再靠 xml:"title" 标签去映射。
常见错误现象:字段定义为 title string,解析后始终为空字符串,且不报错——因为 xml 包直接跳过未导出字段。
- 必须用大写字段名:
Title string、Author string - 标签里写实际 XML 名:
`xml:"title"`、`xml:"author"` - 如果字段是嵌套结构体,同样要导出;切片字段如
Books []Book也要大写
XML 属性要用 ,attr 后缀,不能漏掉逗号
XML 中的属性(如 )和元素内容是完全不同的解析路径。不加 ,attr,encoding/xml 会把它当子元素找,导致字段始终为零值。
示例 XML:
- 书城名称属性:
BookStoreName string `xml:"name,attr"` - 每本书的类别属性:
Category string `xml:"category,attr"` - 漏掉逗号(如写成
xml:"name attr"或xml:"nameattr")会导致解析失败且静默忽略
文本内容(如 09361303)需用 ,chardata 显式提取
像 09361303 这种只含纯文本的标签,其值不是子元素,而是“字符数据”(character data)。若只写 xml:"DATA",Unmarshal 会试图匹配一个叫 DATA 的子结构体,而不是取文本内容。
正确做法是用 ,chardata 告诉解析器:“这个字段存的是标签内的文本”。
- 错误写法:
Data string `xml:"DATA"`→ 字段为空 - 正确写法:
Data string `xml:",chardata"`(注意前面没字段名) - 如果同一标签既有属性又有文本内容,需拆成两个字段:
Value string `xml:",chardata"`+Code string `xml:"code,attr"`
根节点不匹配时,别硬套外层结构体
遇到类似 这种单标签 XML,不要强行定义 type BucketLocation struct { LocationConstraint string `xml:"LocationConstraint"` }。因为 Unmarshal 会尝试把整个 XML 当作 BucketLocation 元素来解析,但实际根节点是 LocationConstraint,必然失败。
两种更稳妥的做法:
- 直接解析为字符串指针:
var s string; xml.Unmarshal(data, &s) - 或定义根名匹配的结构体:
type LocationConstraint struct { XMLName xml.Name `xml:"LocationConstraint"` Value string `xml:",chardata"` } - 用
xml.NewDecoder手动跳过声明或注释(如)更安全,尤其面对不可控来源的 XML
最易被忽略的一点:XML 声明行()本身不是元素,不影响解析,但若手动截断 XML 字符串时误删了根标签起始位置,就会触发 “invalid character entity” 类错误。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











