Go语言XML编解码实战指南

一、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块输出(包裹在<![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))

}

输出结果如下:

四、注意事项

结构体字段必须首字母大写(导出字段)才能被正确解析。

当属性与元素存在命名冲突时,需要显式指定标签进行区分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值