Go结构体适配JSON/XML编码时XML反序列化数组失效问题排查
问题根因与解决方法
这个问题完全可以通过调整XML标签配置解决,不需要改动自定义的反序列化逻辑。
根因分析
Go标准库encoding/xml的元素匹配规则存在序列化/反序列化逻辑不对称的设计缺陷,也是导致你拿到空切片的核心原因:
- 序列化阶段:
Endpoint结构体内部显式定义了带xml:"Endpoint"标签的XMLName字段。序列化时会优先使用元素自身XMLName指定的标签名,忽略切片字段的默认元素名推导结果,因此最终输出大写开头的<Endpoint>元素,和你看到的序列化结果完全一致。 - 反序列化阶段:
Ingress结构体中的Endpoint切片字段没有显式配置XML标签。此时标准库会自动按照默认规则推导匹配的元素名:当字段是大写开头的Go命名(如Endpoint)时,会把首字母转为小写,只会匹配小写开头的<endpoint>元素。你输入的XML是大写开头的<Endpoint>元素,完全无法匹配,最终切片为空。 - JSON流程无此问题:因为
endpoints字段已经显式写了json:"endpoints"标签,JSON编解码全程匹配显式指定的key,因此JSON序列化、反序列化的结果都是正常的。
调整方法
只需要给Ingress结构体中的Endpoint切片字段,显式补充XML标签,指定要匹配的元素名为Endpoint即可,修改后的字段定义为:
type Ingress struct { XMLName xml.Name `json:"-" xml:"Ingress"` Endpoint []Endpoint `json:"endpoints" xml:"Endpoint"` }
修改完成后,反序列化逻辑会正确收集所有同级的<Endpoint>元素到切片中,你自定义的EndpointKind的XML校验逻辑也会正常触发,最终输出和预期完全一致。
内容的提问来源于stack exchange,提问作者Aaditya Kalsi
相关产品推荐
相关产品推荐

