
本文介绍一种简洁、安全、符合 go 语言惯用法的 xml→json 转换方案:先通过 xml.unmarshal 解析 xml 到结构体,再利用 json.marshal 序列化为 json 字节流,避免手动拼接字符串带来的可读性差、易出错等问题。
在 Go 中,将 XML 数据转换为 JSON 并非需要“重写解析逻辑”,而是应充分利用标准库的序列化能力——关键在于统一数据载体(结构体),并借助 encoding/xml 和 encoding/json 两个包协同工作。
✅ 正确做法:结构体驱动的双向序列化
首先定义结构体,并为 XML 和 JSON 分别设置合适的 struct tag。注意:Go 不支持单字段多 tag 的自动映射,因此需确保字段名与语义一致,tag 明确指定解析/序列化规则:
type Root struct {
Type string `xml:"type,attr" json:"type"`
CoverHeadline string `xml:"Head>PageHeadline>p" json:"cover_headline"`
}接着,按顺序执行两步操作:
- XML 解析:使用 xml.Unmarshal 将原始字节切片反序列化为结构体;
- JSON 生成:调用 json.Marshal 将同一结构体序列化为 JSON 字节流(返回 []byte),再写入响应或进一步处理。
完整示例代码如下:
package main
import (
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
)
type Root struct {
Type string `xml:"type,attr" json:"type"`
CoverHeadline string `xml:"Head>PageHeadline>p" json:"cover_headline"`
}
func xmlToJSON(w http.ResponseWriter, r *http.Request) {
// 示例 XML 数据(实际中可能来自请求体或文件)
data := []byte(`
<root type="article">
<Head>
<PageHeadline><p>Go 编程入门指南</p></PageHeadline>
</Head>
</root>`)
var root Root
if err := xml.Unmarshal(data, &root); err != nil {
http.Error(w, "XML 解析失败: "+err.Error(), http.StatusBadRequest)
return
}
// ✅ 安全、可读、可维护:直接 Marshal 到 JSON
jsonData, err := json.Marshal(root)
if err != nil {
http.Error(w, "JSON 序列化失败: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Write(jsonData) // 输出:{"type":"article","cover_headline":"Go 编程入门指南"}
}⚠️ 注意事项与最佳实践
- 避免 fmt.Sprintf 拼接 JSON:不仅易引入格式错误(如未转义引号、嵌套结构失控)、XSS 风险,还完全绕过类型安全和标准库的验证逻辑。
- Struct Tag 必须准确:xml tag 控制 XML 解析路径(如 Head>PageHeadline>p 支持嵌套路径),json tag 控制输出字段名与是否忽略空值(如 ,omitempty)。
- 错误处理不可省略:xml.Unmarshal 和 json.Marshal 均可能失败,尤其在输入非法或字段类型不匹配时,务必检查返回错误。
- 如需更灵活控制(如动态字段、无结构 XML):可考虑第三方库如 github.com/basgys/goxml2json,但对大多数业务场景,标准库 + 结构体已足够健壮高效。
综上,Go 中 XML 转 JSON 的核心范式是:定义清晰结构体 → 用 xml.Unmarshal 加载 → 用 json.Marshal 输出。这一流程简洁、可测试、可扩展,是真正符合 Go “少即是多”哲学的工程化实践。










