当前位置:网站首页>Go 语言入门很简单:Go 处理 XML 文件
Go 语言入门很简单:Go 处理 XML 文件
2022-06-30 11:42:00 【华为云】

读取 XML 文件
先来看一看如何读取本地 XML 文件,同 JSON 数据类似,Go 同样需要一个结构体来接收 XML 的数据。
我们定义一个 test.xml 文件,存取的是员工信息:
<?xml version="1.0" encoding="UTF-8"?><Record> <Name>Yuzhou</Name> <SurName>1su</SurName> <Tel> <Mobile>true</Mobile> <Number>12345678</Number> </Tel> <Tel> <Mobile>true</Mobile> <Number>0755-12345</Number> </Tel></Record>然后我们看到该 XML 有一条记录,所以我们需要两个结构体:Record 和 Telphone :
type Record struct { Name string Surname string Tel []Telephone}type Telephone struct { Mobile bool Number string}然后定义一个 readFromXML() 函数,先读取文件,然后解析该文件:
func readFromXMl(filename string, key interface{}) error { in, err := os.Open(filename) if err != nil { return err } decodeXML := xml.NewDecoder(in) err = decodeXML.Decode(key) if err != nil { return err } in.Close() return nil}最后我们代码的完整部分如下:
package mainimport ( "encoding/xml" "fmt" "os")type Record struct { Name string Surname string Tel []Telephone}type Telephone struct { Mobile bool Number string}func readFromXMl(filename string, key interface{}) error { in, err := os.Open(filename) if err != nil { return err } decodeXML := xml.NewDecoder(in) err = decodeXML.Decode(key) if err != nil { return err } in.Close() return nil}func main() { arguments := os.Args if len(arguments) == 1 { fmt.Println("Please provide a filename!") return } filename := arguments[1] var myRecord Record err := readFromXMl(filename, &myRecord) if err == nil { fmt.Println("XML:", myRecord) } else { fmt.Println(err) }}在终端执行该代码,得到如下结果:
$ go run main.go test.xml XML: {Yuzhou [{true 12345678} {true 0755-12345}]}解析 XML
Go 有一个使用 NewParser()创建的 XML 解析器。 这需要一个 io.Reader() 作为参数并返回一个指向 Parser 的指针。 如果 XML 文件在用户标签、嵌套元素上设置了属性,如果您能够解析这些属性,那么通过扩展,您应该能够解析任何大小的 XML 文件。
现在新建另一个 test.xml 文件:
<?xml version="1.0" encoding="utf-8"?><servers version="1"> <server> <serverName>Shanghai_VPN</serverName> <serverIP>127.0.0.1</serverIP> </server> <server> <serverName>Beijing_VPN</serverName> <serverIP>127.0.0.2</serverIP> </server></servers>如何解析如上这个 XML 文档呢?我们可以透过 xml 模块的 Unmarshal() 函数来达到我们的目的:
func Unmarshal(data []byte, v interface{}) errordata 接收的是 XML 文件流,v 是需要输出的结构,定义为 interface,也就是可以把 XML 转换为任意的格式。我们这里主要介绍 struct 的转换,因为 struct 和 XML 都有类似树状结构的特征。
定义我们的结构体:
type Recurlyservers struct { XMLName xml.Name `xml:"servers"` Version string `xml:"version,attr"` Svs []server `xml:"server"` Description string `xml:",innerxml"`}type server struct { XMLName xml.Name `xml:"server"` ServerName string `xml:"serverName"` ServerIP string `xml:"serverIP"`}完整代码:
package mainimport ( "encoding/xml" "fmt" "io/ioutil" "os")type Recurlyservers struct { XMLName xml.Name `xml:"servers"` Version string `xml:"version,attr"` Svs []server `xml:"server"` Description string `xml:",innerxml"`}type server struct { XMLName xml.Name `xml:"server"` ServerName string `xml:"serverName"` ServerIP string `xml:"serverIP"`}func main() { file, err := os.Open("test.xml") // For read access. if err != nil { fmt.Printf("error: %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.Println(v)}XML 本质上是一种树状结构,而我们可以定义与之匹配的 go 语言的结构体类型,然后通过xml.Unmarshal 来将 xml 中的文件解析成对应的 struct 结构体。如上例子输出如下结果:
{{ servers} 1 [{{ server} Shanghai_VPN 127.0.0.1} {{ server} Beijing_VPN 127.0.0.2}]<server> <serverName>Shanghai_VPN</serverName> <serverIP>127.0.0.1</serverIP></server><server> <serverName>Beijing_VPN</serverName> <serverIP>127.0.0.2</serverIP></server>}上面的例子中,将 xml 文件解析成对应的 struct 结构体是通过 xml.Unmarshal 来完成的,
这个过程是如何实现的?可以看到我们的 struct 定义后面多了一些类似于 xml:"serverName" 这样的内容,这个是 struct 的一个特性,它们被称为 struct tag,它们是用来辅助反射的。我们来看一下 Unmarshal 的定义:
func Unmarshal(data []byte, v interface{}) error我们看到函式定义了两个参数,第一个是 XML 文件流,第二个是储存的对应类型,目前支持:
结构体 struct
切片 slice
字符串 string
XML 套件内部采用了反射来进行文件的对映,所以 v 里面的位置必须是输出的。Unmarshal 解析的时候 XML 元素和对应类型怎么对应起来的呢?
利用一个先后顺序读取:首先会读取 struct tag,如果没有,那么就会对应栏位名。必须注意一点的是解析的时候 tag、栏位名、XML 元素都是区分大小写的的,所以必须一一对应。
解析 XML 到 struct 的时候遵循如下的规则:
如果 struct 的第二个参数是
string或者[]byte型,并且它的 tag 含有",innerxml",Unmarshal将会将此位置所对应的元素内所有内嵌的原始 xml 累加到此位置上,如上面例子 Description 定义。最后的输出是:
<server> <serverName>Shanghai_VPN</serverName> <serverIP>127.0.0.1</serverIP> </server> <server> <serverName>Beijing_VPN</serverName> <serverIP>127.0.0.2</serverIP> </server>总结
本文主要介绍了如何读取本地 XML 文件和解析 XML 文件,分别使用 Go 的 encoding/ XML 包中的 NewDecoder() 和 Unmarshal() 函数。之后再去探索更多的用法,比如在 Web 开发中读取配置文件,或者接收 XML 文件格式的文件。下一篇文章将会介绍如何将 Go 数据转化为 XML 文件。
边栏推荐
- R language ggplot2 visualization: use ggplot2 to visualize the scatter diagram, and_ Set the alpha parameter in the point parameter to specify the transparency level of data points (points transparent
- Using cookie technology to realize historical browsing records and control the number of displays
- There are so many kinds of coupons. First distinguish them clearly and then collect the wool!
- koa - 洋葱模型浅析
- Lucene full text search toolkit learning notes summary
- wallys/3×3 MIMO 802.11ac Mini PCIe Wi-Fi Module, QCA9880, 2,4GHz / 5GHzDesigned for Enterprise
- R language ggplot2 visualization: use ggplot2 to visualize the scatter diagram and use scale_ color_ viridis_ D function specifies the color scheme of data points
- R language ggplot2 visual Facet: gganimate package is based on Transition_ The time function creates a dynamic scatter graph animation (GIF) and uses the labs function to add a dynamic time title to t
- How can c write an SQL parser
- R语言ggplot2可视化:使用ggplot2可视化散点图、使用scale_color_viridis_d函数指定数据点的配色方案
猜你喜欢

60 divine vs Code plug-ins!!

Object mapping - mapping Mapster

EMC surge

"New digital technology" completed tens of millions of yuan of a + round financing and built an integrated intelligent database cloud management platform

盘点那些具有特色的写作软件

wallys/600VX – 2 × 2 MIMO 802.11ac Mini PCIe Wi-Fi Module, Dual Band, 2,4GHz / 5GHz QCA 9880

一个悄然崛起的国产软件,低调又强大!

zabbix监控TCP连接个数

The sci-fi ideas in these movies have been realized by AI

来聊聊怎么做硬件兼容性检测,快速迁移到openEuler?
随机推荐
shell第一个命令结果传入第二个命令删除
【云原生 | Kubernetes篇】深入了解Deployment(八)
1254. 统计封闭岛屿的数目
1175. 质数排列
智慧法院新征程,无纸化办公,护航智慧法院绿色庭审
据说用了这个,老板连夜把测试开了
21、wpf之绑定使用小记
Uncover the whole link communication process of customer service im
How can c write an SQL parser
安装onnx很慢,使用清华镜像
他是上海两大产业的第一功臣,却在遗憾中默默离世
深入解析 Apache BookKeeper 系列:第四篇—背压
time 函数和 clock_gettime()函数的区别
zabbix监控TCP连接个数
对象映射 - Mapping.Mapster
来聊聊怎么做硬件兼容性检测,快速迁移到openEuler?
R language ggplot2 visualization: gganimate package is based on Transition_ Time function to create dynamic scatter animation (GIF)
Redis - ziplist compressed list
R language ggplot2 visualization: use ggplot2 to visualize the scatter diagram and use scale_ x_ The log10 function configures the value range of the X axis to be logarithmic coordinates
线下门店为什么要做新零售?