在Go语言中,encoding/xml
包用于处理XML数据的编码和解码。这个包提供了Marshal
和Unmarshal
函数,用于将Go语言的结构体序列化为XML格式,以及将XML数据反序列化为Go语言的结构体。
实现原理
- Marshal:将Go结构体转换为XML格式的字符串。这个过程中,会遍历结构体的字段,并根据字段的tag(标签)信息(如
xml:"name,attr"
指定字段名为name
且作为属性)来决定如何在XML中表示。 - Unmarshal:将XML格式的字符串解析为Go语言的结构体。它会根据XML的结构和元素名来匹配结构体的字段,并填充数据。
使用示例
下面是一个简单的使用encoding/xml
包进行XML编解码的示例:
package main
import (
"encoding/xml"
"fmt"
"os"
)
// 定义与XML结构对应的Go结构体
type Person struct {
XMLName xml.Name `xml:"person"` // 指定XML的根元素名
Id int `xml:"id,attr"` // 指定Id字段为XML的属性
FirstName string `xml:"first_name"` // 指定字段在XML中的元素名
LastName string `xml:"last_name"`
Email string `xml:"email,omitempty"` // 如果Email为空,则不生成XML元素
}
func main() {
// 编码示例
p := Person{Id: 1, FirstName: "John", LastName: "Doe", Email: "john.doe@example.com"}
output, err := xml.MarshalIndent(p, "", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
}
os.Stdout.Write(output)
fmt.Println() // 换行以便清晰查看输出
// 解码示例
xmlStr := `
<person id="2">
<first_name>Jane</first_name>
<last_name>Doe</last_name>
</person>
`
var p2 Person
err = xml.Unmarshal([]byte(xmlStr), &p2)
if err != nil {
fmt.Printf("error: %v\n", err)
}
fmt.Printf("%+v\n", p2)
}
输出
编码(Marshal)的输出示例(格式化后):
<person id="1">
<first_name>John</first_name>
<last_name>Doe</last_name>
<email>john.doe@example.com</email>
</person>
解码(Unmarshal)后的结构体打印(%+v
用于显示字段名和值):
{XMLName:{Space:"" Local:"person"} Id:2 FirstName:Jane LastName:Doe Email:}
注意
- 结构体字段的
xml
标签用于控制XML编码和解码的行为。 xml.MarshalIndent
用于生成格式化的XML输出,其中第二个和第三个参数分别控制缩进级别和前缀。omitempty
选项用于Unmarshal
时忽略空的XML元素,以及Marshal
时如果字段值为空(如空字符串、零值等)则不生成对应的XML元素。- 结构体中的
XMLName
字段用于指定XML的根元素名称。如果不需要指定根元素,可以省略此字段。