在Golang开发中,将数据序列化为符合规范的XML格式是常见需求,标准库的encoding/xml包提供了完整的XML读写能力,通过合理的结构体定义和标签配置,就能生成符合规范的XML数据并写入文件。

核心依赖与基础概念
Golang处理XML写入主要依赖encoding/xml包,该包提供了Marshal、MarshalIndent等方法将Go数据结构转换为XML字节流,同时支持自定义结构体标签来控制XML元素的名称、属性、嵌套规则等。符合规范的XML需要满足几个基本条件:有正确的XML声明头、元素标签闭合、特殊字符正确转义、编码统一。
基础XML数据生成
首先定义对应的结构体,通过结构体标签指定XML元素的相关属性,然后使用MarshalIndent生成格式化的XML数据,最后写入文件即可。
package main
import (
"encoding/xml"
"os"
)
// 定义XML根元素对应的结构体
// xml.Name字段可以指定根元素的名称
type User struct {
XMLName xml.Name `xml:"user"` // 根元素名为user
ID int `xml:"id"` // 子元素id
Name string `xml:"name"` // 子元素name
Age int `xml:"age"` // 子元素age
}
func main() {
// 初始化数据
u := User{
ID: 1001,
Name: "张三",
Age: 25,
}
// 生成带缩进的XML数据,第一个参数是前缀,第二个参数是缩进符
data, err := xml.MarshalIndent(u, "", " ")
if err != nil {
panic(err)
}
// 添加XML声明头
xmlHeader := []byte(xml.Header)
// 拼接完整的XML数据
fullData := append(xmlHeader, data...)
// 写入文件
err = os.WriteFile("user.xml", fullData, 0644)
if err != nil {
panic(err)
}
}
运行上述代码后,会生成如下的user.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <user> <id>1001</id> <name>张三</name> <age>25</age> </user>
生成带属性的XML元素
如果需要在XML元素上添加属性,可以在结构体标签中通过attr标记来指定,属性会作为元素的属性而不是子元素存在。
package main
import (
"encoding/xml"
"os"
)
type Book struct {
XMLName xml.Name `xml:"book"`
// id作为book元素的属性,attr标记表示是属性
ID string `xml:"id,attr"`
Title string `xml:"title"`
Author string `xml:"author"`
Price float64 `xml:"price"`
}
func main() {
b := Book{
ID: "bk001",
Title: "Golang编程入门",
Author: "李四",
Price: 59.9,
}
data, err := xml.MarshalIndent(b, "", " ")
if err != nil {
panic(err)
}
fullData := append([]byte(xml.Header), data...)
os.WriteFile("book.xml", fullData, 0644)
}
生成的XML内容如下:
<?xml version="1.0" encoding="UTF-8"?> <book id="bk001"> <title>Golang编程入门</title> <author>李四</author> <price>59.9</price> </book>
处理嵌套结构的XML
当XML存在多层嵌套结构时,只需要在结构体中嵌套对应的子结构体即可,通过结构体标签指定子元素的名称。
package main
import (
"encoding/xml"
"os"
)
// 地址结构体,作为User的子元素
type Address struct {
City string `xml:"city"`
Street string `xml:"street"`
ZipCode string `xml:"zip_code"`
}
type User struct {
XMLName xml.Name `xml:"user"`
ID int `xml:"id"`
Name string `xml:"name"`
// 嵌套Address结构体,指定子元素名为address
Addr Address `xml:"address"`
}
func main() {
u := User{
ID: 1002,
Name: "王五",
Addr: Address{
City: "北京",
Street: "中关村大街",
ZipCode: "100080",
},
}
data, err := xml.MarshalIndent(u, "", " ")
if err != nil {
panic(err)
}
fullData := append([]byte(xml.Header), data...)
os.WriteFile("user_nested.xml", fullData, 0644)
}
生成的嵌套XML如下:
<?xml version="1.0" encoding="UTF-8"?>
<user>
<id>1002</id>
<name>王五</name>
<address>
<city>北京</city>
<street>中关村大街</street>
<zip_code>100080</zip_code>
</address>
</user>
XML规范注意事项
- 特殊字符转义:XML中的
<、>、&、"、'等特殊字符会被自动转义,不需要手动处理,encoding/xml包会自动完成该工作。 - 编码设置:默认的XML声明头编码是UTF-8,如果需要其他编码,可以手动修改声明头,但是需要确保写入文件时使用的编码和声明一致。
- 空值处理:如果结构体字段是零值,默认会被序列化到XML中,如果不想输出零值字段,可以在标签中添加
omitempty标记,例如xml:"age,omitempty"。 - CDATA块处理:如果需要在XML中输出大段的文本且不想被转义,可以使用
xml:"CDATA"标签,结构体字段类型为string即可,序列化时会自动包裹CDATA块。
CDATA块使用示例
package main
import (
"encoding/xml"
"os"
)
type Article struct {
XMLName xml.Name `xml:"article"`
Title string `xml:"title"`
// 内容字段使用CDATA标记,不会被转义
Content string `xml:"content,CDATA"`
}
func main() {
a := Article{
Title: "技术分享",
Content: "这是一段包含特殊字符的内容:演示 ",
}
data, err := xml.MarshalIndent(a, "", " ")
if err != nil {
panic(err)
}
fullData := append([]byte(xml.Header), data...)
os.WriteFile("article.xml", fullData, 0644)
}
生成的article.xml中content内容会被包裹在CDATA块中:
<?xml version="1.0" encoding="UTF-8"?> <article> <title>技术分享</title> <content><![CDATA[这是一段包含特殊字符的内容:<test>演示</test>]]></content> </article>
GolangXML写入XML规范encoding_xml数据序列化修改时间:2026-06-12 22:24:43