
本文介绍使用 go 标准库 encoding/xml 与 encoding/json 配合,实现 xml 到 json 的类型安全、可维护转换,避免手动拼接字符串,提升代码可读性与健壮性。
在 Go 中将 XML 转换为 JSON,最推荐的方式是先反序列化为结构体(xml.Unmarshal),再序列化为 JSON(json.Marshal)——这不仅语义清晰、类型安全,还能复用结构体标签统一管理字段映射,彻底替代易出错的 fmt.Sprintf 字符串拼接。
✅ 正确做法:双阶段标准库转换
首先定义结构体,并同时声明 xml 和 json 标签,确保字段在两种格式间正确映射:
type Root struct {
Type string `xml:"type,attr" json:"type"`
CoverHeadline string `xml:"Head>PageHeadline>p" json:"cover_headline"`
}
// 若需嵌套结构(如示例中的 "entry"),建议显式建模
type Response struct {
Type string `json:"type"`
Action string `json:"action"`
Entry Entry `json:"entry"`
}
type Entry struct {
AdsEnabled int `json:"ads_enabled"`
CommentsEnabled int `json:"comments_enabled"`
CoverHeadline string `json:"cover_headline"`
}然后执行两步转换:
var root Root
if err := xml.Unmarshal(data, &root); err != nil {
http.Error(w, "Invalid XML: "+err.Error(), http.StatusBadRequest)
return
}
// 构建目标 JSON 结构(非硬编码,逻辑清晰)
response := Response{
Type: root.Type,
Action: "save",
Entry: Entry{
AdsEnabled: 1,
CommentsEnabled: 0,
CoverHeadline: root.CoverHeadline,
},
}
jsonBytes, err := json.Marshal(response)
if err != nil {
http.Error(w, "JSON marshal failed: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(jsonBytes)⚠️ 注意事项与最佳实践
- 标签一致性:xml 和 json 标签可独立设置(如 xml:"p" + json:"headline"),无需相同名称,但应语义对齐;
- 空值处理:json.Marshal 默认忽略零值字段;如需保留 null,可为字段添加 json:",omitempty" 或使用指针类型(如 *string);
- 嵌套与命名空间:XML 命名空间(如 xmlns:xsi)需在结构体中用 xml:"prefix:tag" 显式处理;复杂嵌套建议分层建模,而非扁平化单结构体;
- 性能考量:对于超大 XML 文件,可考虑流式解析(xml.Decoder)+ 增量构建 JSON,但多数场景下 Unmarshal → Marshal 已足够高效;
- 错误不可忽略:xml.Unmarshal 和 json.Marshal 均返回 error,生产环境必须校验,避免静默失败。
✅ 总结
用 encoding/xml.Unmarshal + encoding/json.Marshal 是 Go 生态中 XML→JSON 转换的标准、安全、可维护方案。它消除了字符串拼接带来的注入风险、格式错误和维护成本,借助结构体作为中间契约,使数据流清晰可控。配合合理的结构设计与错误处理,即可构建高可靠性 API 数据转换逻辑。










