一、encoding/xml介绍
Go语言通过encoding/xml包实现对XML数据的编解码操作,该功能利用结构体标签(Struct Tags)在XML元素与Go结构体字段之间建立映射关系。
二、XML解析与生成
1)将结构体转换为XML
使用 xml.Marshal或xml.MarshalIndent(用于格式化输出)将结构体转换为 XML 数据。代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
}
func main() {
user := UserInfo{
UserName: "张三",
Age: 26,
}
userXml1, _ := xml.MarshalIndent(user, "", " ")
fmt.Println("格式化输出:")
fmt.Println(string(userXml1))
userXml2, _ := xml.Marshal(user)
fmt.Println("\n非格式化输出:")
fmt.Println(string(userXml2))
}
输出结果如下:

2)将XML转换为结构体
通过xml.Unmarshal解析XML数据时,需要预先定义与XML结构相匹配的Go结构体,并使用xml标签来指定字段映射规则。
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
}
func main() {
userXmlStr := "<user><name>张三</name><age>25</age></user>"
var userInfo UserInfo
xml.Unmarshal([]byte(userXmlStr), &userInfo)
fmt.Println("name:", userInfo.UserName)
fmt.Println("age:", userInfo.Age)
}
执行结果如下:

三、注解标签
1)常用标签
常用标签格式如下:
| 标签格式 | 作用描述 |
|---|---|
xml:"name" | 映射XML元素名到结构体字段 |
xml:"name,attr" | 将字段映射为XML元素的属性 |
xml:",chardata" |
作为纯文本内容输出(非XML标签) |
xml:",cdata" |
为CDATA块输出(包裹在 |
xml:",innerxml" | 保留原始XML片段(包括标签) |
xml:",comment" | 捕获XML注释内容,内容中不能包含--字符串 |
xml:"a>b>c" | 嵌套路径映射,匹配多层子元素 |
xml:"-" | 忽略字段 |
xml:"omitempty" | 在字段为空时省略输出 |
2)xml:"name"
映射XML元素名到结构体字段,代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
}
转换为xml字符串如下:
<user>
<name>张三</name>
<age>26</age>
</user>
3)xml:"name,attr"
将字段映射为XML元素的属性,代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name,attr"`
// 年龄,xml标签age
Age int `xml:"age"`
}
转换为xml字符串如下:
<user name="张三">
<age>26</age>
</user>
4)xml:",chardata"
作为纯文本内容输出(非XML标签),代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name,attr"`
// 年龄,xml标签age
Age int `xml:"age"`
// 年龄,xml标签age
Addr string `xml:",chardata"`
}
转换为xml字符串如下:
<user name="张三">
<age>26</age>北京
</user>
5)xml:",cdata"
作为CDATA块输出(包裹在<![CDATA[ ... ]]>中),代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name,attr"`
// 年龄,xml标签age
Age int `xml:"age"`
// 年龄,xml标签age
Addr string `xml:",cdata"`
}
转换为xml字符串如下:
<user name="张三">
<age>26</age><![CDATA[北京]]>
</user>
6)xml:",innerxml"
保留原始XML片段(包括标签),代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
// 内容
Content string `xml:",innerxml"`
}
func main() {
userXmlStr := "<user><name>张三</name><age>25</age><addr>北京</addr></user>"
var userInfo UserInfo
xml.Unmarshal([]byte(userXmlStr), &userInfo)
fmt.Println("content:", userInfo.Content)
}
输出结果如下:

7)xml:",comment"
作为XML注释输出(内容中不得包含--字符串),代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
// 内容
Comment string `xml:",comment"`
}
func main() {
user := UserInfo{
UserName: "张三",
Age: 26,
Comment: "这是注释",
}
userXml1, _ := xml.MarshalIndent(user, "", " ")
fmt.Println("格式化输出:")
fmt.Println(string(userXml1))
userXml2, _ := xml.Marshal(user)
fmt.Println("\n非格式化输出:")
fmt.Println(string(userXml2))
}
输出结果如下:

8)xml:"a>b>c"
嵌套路径映射,匹配多层子元素,代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
// 地址信息
Addr string `xml:"addrInfo>addr"`
}
转换为xml字符串如下:
<user>
<name>张三</name>
<age>26</age>
<addrInfo>
<addr>北京</addr>
</addrInfo>
</user>
9)xml:"-"
忽略字段,代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
// 地址信息
Addr string `xml:"-"`
}
func main() {
user := UserInfo{
UserName: "张三",
Age: 26,
Addr: "北京",
}
userXml1, _ := xml.MarshalIndent(user, "", " ")
fmt.Println("格式化输出:")
fmt.Println(string(userXml1))
userXml2, _ := xml.Marshal(user)
fmt.Println("\n非格式化输出:")
fmt.Println(string(userXml2))
}
输出结果如下:

10)xml:"omitempty"
在字段为空时省略输出,代码示例如下:
// UserInfo 定义用户信息xml对应结构体
type UserInfo struct {
// xml根标签user
XMLName xml.Name `xml:"user"`
// 用户名称,xml标签name
UserName string `xml:"name"`
// 年龄,xml标签age
Age int `xml:"age"`
// 地址信息
Addr string `xml:"addr,omitempty"`
}
func main() {
user := UserInfo{
UserName: "张三",
Age: 26,
Addr: "北京",
}
userXml1, _ := xml.MarshalIndent(user, "", " ")
fmt.Println("输出:")
fmt.Println(string(userXml1))
user.Addr = ""
userXml2, _ := xml.MarshalIndent(user, "", " ")
fmt.Println("\n输出:")
fmt.Println(string(userXml2))
}
输出结果如下:

四、注意事项
结构体字段必须首字母大写(导出字段)才能被正确解析。
当属性与元素存在命名冲突时,需要显式指定标签进行区分。
652

被折叠的 条评论
为什么被折叠?



