go语言xml文件的解析及生成代码示例

本文介绍使用Go语言进行XML文件的解析和序列化的具体方法。包括如何定义结构体以便于XML解析,如何利用Go标准库实现XML文件读取及内容解析,以及如何将Go语言中的数据结构转换为XML格式并写入文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<?xml version="1.0" encoding="utf-8"?>
<servers1 version="1">
<server>
<serverName>Shanghai_VPN</serverName>
<serverIP>127.0.0.1</serverIP>
</server>
<server1>
<serverName>Beijing_VPN</serverName>
<serverIP>127.0.0.2</serverIP>
</server1>
</servers1>

package main

/*如果struct中有一个叫做XMLName,且类型为xml.Name字段,那么在解析的时候就会保存这个element的名字到该字段,如上面例子中的servers。
如果某个struct字段的tag定义中含有XML结构中element的名称,那么解析的时候就会把相应的element值赋值给该字段,如上servername和serverip定义。
如果某个struct字段的tag定义了中含有",attr",那么解析的时候就会将该结构所对应的element的与字段同名的属性的值赋值给该字段,如上version定义。
如果某个struct字段的tag定义 型如"a>b>c",则解析的时候,会将xml结构a下面的b下面的c元素的值赋值给该字段。
如果某个struct字段的tag定义了"-",那么不会为该字段解析匹配任何xml数据。
如果struct字段后面的tag定义了",any",如果他的子元素在不满足其他的规则的时候就会匹配到这个字段。
如果某个XML元素包含一条或者多条注释,那么这些注释将被累加到第一个tag含有",comments"的字段上,
这个字段的类型可能是[]byte或string,如果没有这样的字段存在,那么注释将会被抛弃
*/
import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
)

// 为了正确解析,go语言的xml包要求struct定义中的所有字段必须是可导出的(即首字母大写)
type Recurlyservers struct {
    XMLName xml.Name `xml:"servers1"` //这个是struct的一个特性,它们被称为 struct tag,它们是用来辅助反射的
    Version string `xml:"version,attr"`
    Svs []server `xml:"server"`
    Description string `xml:",innerxml"` //如果struct的一个字段是string或者[]byte类型且它的tag含有",innerxml"Unmarshal将会将此字段所对应的元素内所有内嵌的原始xml累加到此字段上
}

type server struct {
    XMLName xml.Name `xml:"server"`
    ServerName string `xml:"serverName"`
    ServerIP string `xml:"serverIP"`
}

func mainRead() {
    file, err := os.Open("server.xml")
    if err != nil {
        fmt.Printf("open err %v", err)
        return
    }
    defer file.Close()
    data, err := ioutil.ReadAll(file)
    if err != nil {
        fmt.Printf("error %v", err)
        return
    }
    v := Recurlyservers{}
    err = xml.Unmarshal(data, &v)
    if err != nil {
        fmt.Printf("error %v", err)
        return
    }
    fmt.Print("**************\n")
    fmt.Println(v)

}

/* write xml file */
/*我们看到Marshal函数接收的参数v是interface{}类型的,即它可以接受任意类型的参数,那么xml包,根据什么规则来生成相应的XML文件呢?+

如果v是 array或者slice,那么输出每一个元素,类似value
如果v是指针,那么会Marshal指针指向的内容,如果指针为空,什么都不输出
如果v是interface,那么就处理interface所包含的数据
如果v是其他数据类型,就会输出这个数据类型所拥有的字段信息
生成的XML文件中的element的名字又是根据什么决定的呢?元素名按照如下优先级从struct中获取:
如果v是struct,XMLName的tag中定义的名称
类型为xml.Name的名叫XMLName的字段的值
通过struct中字段的tag来获取
通过struct的字段名用来获取
marshall的类型名称
我们应如何设置struct 中字段的tag信息以控制最终xml文件的生成呢?
XMLName不会被输出
tag中含有"-"的字段不会输出
tag中含有"name,attr",会以name作为属性名,字段值作为值输出为这个XML元素的属性,如上version字段所描述
tag中含有",attr",会以这个struct的字段名作为属性名输出为XML元素的属性,类似上一条,只是这个name默认是字段名了。
tag中含有",chardata",输出为xml的 character data而非element。
tag中含有",innerxml",将会被原样输出,而不会进行常规的编码过程
tag中含有",comment",将被当作xml注释来输出,而不会进行常规的编码过程,字段值中不能含有"--"字符串
tag中含有"omitempty",如果该字段的值为空值那么该字段就不会被输出到XML,空值包括:false、0、nil指针或nil接口,任何长度为0的array, slice, map或者string
tag中含有"a>b>c",那么就会循环输出三个元素a包含b,b包含c*/

type wservers struct {
    XMLName xml.Name `xml:"servers"`
    Version string `xml:"version,attr`
    Svs []wserver `xml:"server"`
}

type wserver struct {
    ServerName string `xml:"servername"`
    ServerIP string `xml:"serverip`
}

func main() {
    v := &wservers{Version: "1"}
    v.Svs = append(v.Svs, wserver{"zhuji_vpn", "127.0.0.1"})
    v.Svs = append(v.Svs, wserver{"hangzhou_vpn", "123.2.1.0"})
    output, err := xml.MarshalIndent(v, " ", " ")
    if err != nil {
        fmt.Printf("error %v", err)
        return
    }
    file, _ := os.Create("sqn.xml")
    defer file.Close()
    file.Write([]byte(xml.Header))
    file.Write(output)

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值