Go 语言入门很简单:Go 处理 XML 文件(下)

简介: 先来看一看如何读取本地 XML 文件,同 JSON 数据类似,Go 同样需要一个结构体来接收 XML 的数据。

解析 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{}) error

data 接收的是 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 main
import (
  "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 文件格式的文件。

相关文章
|
1月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
191 4
|
2月前
|
Linux Go iOS开发
Go语言100个实战案例-进阶与部署篇:使用Go打包生成可执行文件
本文详解Go语言打包与跨平台编译技巧,涵盖`go build`命令、多平台构建、二进制优化及资源嵌入(embed),助你将项目编译为无依赖的独立可执行文件,轻松实现高效分发与部署。
|
1月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟蒋星熠Jaxonic,Go语言探索者。深耕云计算、微服务与并发编程,以代码为笔,在二进制星河中书写极客诗篇。分享Go核心原理、性能优化与实战架构,助力开发者掌握云原生时代利器。#Go语言 #并发编程 #性能优化
352 43
Go语言深度解析:从入门到精通的完整指南
|
1月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
130 1
|
2月前
|
Cloud Native 安全 Java
Go语言深度解析:从入门到精通的完整指南
🌟 蒋星熠Jaxonic,执着的星际旅人,用Go语言编写代码诗篇。🚀 Go语言以简洁、高效、并发为核心,助力云计算与微服务革新。📚 本文详解Go语法、并发模型、性能优化与实战案例,助你掌握现代编程精髓。🌌 从goroutine到channel,从内存优化到高并发架构,全面解析Go的强大力量。🔧 实战构建高性能Web服务,展现Go在云原生时代的无限可能。✨ 附技术对比、最佳实践与生态全景,带你踏上Go语言的星辰征途。#Go语言 #并发编程 #云原生 #性能优化
|
3月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
348 0
|
3月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
222 0
|
9月前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
12月前
|
存储 负载均衡 监控
如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
在数字化时代,构建高可靠性服务架构至关重要。本文探讨了如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
277 1
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。