Golang XML Unmarshalling后序列化出现乱码及命名空间丢失问题
Golang XML序列化保留命名空间及格式解决方案
问题根因
- 自动生成的结构体未正确配置XML命名空间前缀,也没有保留命名空间声明属性,导致序列化时前缀丢失
- 结构体中多余的
chardata类型字段存储了原XML的空白换行字符,序列化时被转义为
实体编码 - 标准库
xml.Marshal默认不会输出XML版本声明,且无格式化缩进
1. 修正结构体定义
删除无用的chardata字段,在XML标签中补充命名空间前缀,新增命名空间声明属性:
package main import "encoding/xml" type VMAP struct { XMLName xml.Name `xml:"vmap:VMAP"` XMLNSVmap string `xml:"xmlns:vmap,attr"` Version string `xml:"version,attr"` AdBreak AdBreak `xml:"vmap:AdBreak"` } type AdBreak struct { User string `xml:"User,attr"` Device string `xml:"device,attr"` Ad []Ad `xml:"Ad"` } type Ad struct { ID string `xml:"id,attr"` Sequence string `xml:"sequence,attr"` Duration string `xml:"Duration"` }
2. 修正序列化逻辑
手动补充XML版本声明,使用带缩进的XML编码器输出,格式与原输入完全匹配:
// 假设model已经完成修改逻辑 model.XMLNSVmap = "http://www.iab.net/vmap-1.0" // 固定命名空间值 var resBuffer bytes.Buffer // 写入XML声明头 resBuffer.WriteString(`<?xml version="1.0" encoding="UTF-8"?>` + "\n") // 初始化编码器,设置缩进和原XML一致(3个空格) encoder := xml.NewEncoder(&resBuffer) encoder.Indent("", " ") // 执行序列化 if err := encoder.Encode(model); err != nil { // 自行处理错误逻辑 panic(err) } // 最终输出的字节数组,可直接返回给HTTP响应 resultXml := resBuffer.Bytes()
效果说明
以上方案输出的XML会完整保留vmap:VMAP、vmap:AdBreak命名空间前缀,自动匹配原XML的缩进格式,无多余的
转义字符,且带标准XML版本声明,和原输入示例格式完全一致。
内容的提问来源于stack exchange,提问作者Indhumathi Murugesan
相关产品推荐
相关产品推荐

