GO输出 XML

简介: GO输出 XML

输出 XML
假若我们不是要解析如上所示的 XML 文件,而是生成它,那么在 go 语言中又该如何实现
呢? xml 包中提供了 Marshal 和 MarshalIndent 两个函数,来满足我们的需求。这两个函数
主要的区别是第二个函数会增加前缀和缩进,函数的定义如下所示:
func Marshal(v interface{}) ([]byte, error)
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
两个函数第一个参数是用来生成 XML 的结构定义类型数据,都是返回生成的 XML 数据流。
下面我们来看一下如何输出如上的 XML:
package main
import (
"encoding/xml"
"fmt"
"os"
)
type Servers struct {
XMLName xml.Name xml:"servers"
Version string xml:"version,attr"
Svs []server xml:"server"
}
type server struct {
ServerName string xml:"serverName"
ServerIP string xml:"serverIP"
}
func main() {
v := &Servers{Version: "1"}
v.Svs = append(v.Svs, server{"Shanghai_VPN", "127.0.0.1"})
v.Svs = append(v.Svs, server{"Beijing_VPN", "127.0.0.2"})
output, err := xml.MarshalIndent(v, " ", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
}
os.Stdout.Write([]byte(xml.Header))
os.Stdout.Write(output)
}
上面的代码输出如下信息:
<?xml version="1.0" encoding="UTF-8"?>


Shanghai_VPN
127.0.0.1


Beijing_VPN
127.0.0.2


和我们之前定义的文件的格式一模一样,之所以会有 os.Stdout.Write([]byte(xml.Header))
这句代码的出现,是因为 xml.MarshalIndent 或者 xml.Marshal 输出的信息都是不带 XML 头
的,为了生成正确的 xml 文件,我们使用了 xml 包预定义的 Header 变量。
我们看到 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 的字段的值
• 通过 strcut 中字段的 tag 来获取
• 通过 strcut 的字段名用来获取
• 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,例如如下代
码就会输出
• FirstName string xml:"name>first"
• LastName string xml:"name>last"


• Asta
• Xie

上面我们介绍了如何使用 Go 语言的 xml 包来编/解码 XML 文件,重要的一点是对 XML 的
所有操作都是通过 struct tag 来实现的,所以学会对 struct tag 的运用变得非常重要,在文
章中我们简要的列举了如何定义 tag。更多内容或 tag 定义请参看相应的官方资料。

目录
相关文章
|
存储 缓存 开发工具
AppsFlyer 研究(二)应用内事件
AppsFlyer 研究(二)应用内事件
1292 0
|
前端开发 API 开发者
使用React实现左侧菜单栏
使用React实现左侧菜单栏
3526 0
|
Python 数据挖掘 自然语言处理
Python---qq群聊天记录词云分析
python拥有近13w个第三方库,其中有很多优秀的库,比如wordcloud,scipy,jieba等库,能快速实现很多功能,比如制作一个QQ群聊天记录词云…… 工具:PyCharm, Python3.6.5 1.获取数据源 qq左下角 导出消息记录 要用.txt导出到任意盘符,接下来就要对导出的txt文件进行数据分析。
3138 0
|
Python
Python教程:一文了解如何使用Lambda 表达式和 filter函数实现过滤器
在 Python 中,Lambda 表达式是一种匿名函数,也就是没有名称的函数。它允许您快速定义简单的单行函数,通常用于函数式编程中的一些场景,例如在高阶函数中作为参数传递。
1146 2
|
存储 编译器 C语言
从C语言到C++_23(多态)抽象类+虚函数表VTBL+多态的面试题(下)
从C语言到C++_23(多态)抽象类+虚函数表VTBL+多态的面试题
536 1
|
安全 Linux 网络安全
深入探索:Kali Linux 网络安全之旅
"Kali" 可能指的是 Kali Linux,它是一种基于 Debian 的 Linux 发行版,专门用于渗透测试、网络安全评估、数字取证和相关的安全任务。Kali Linux 旨在提供一系列用于测试网络和系统安全性的工具,以及为安全专业人员和爱好者提供一个强大的平台。
461 1
|
算法 Java
【数据结构】字符串匹配|BF算法|KMP算法|next数组的优化
【数据结构】字符串匹配|BF算法|KMP算法|next数组的优化
781 0
|
机器学习/深度学习 人工智能 开发框架
人工智能岗位可以考什么证书?考试难不难?
最近几年人工智能在市场上的热度越来越大,很多企业都会利用这个项目来发展自己新渠道,那么想进入这一行的人需要怎么提升自己的技能呢?
人工智能岗位可以考什么证书?考试难不难?
|
JavaScript C# Windows
【傻瓜级JS-DLL-WINCC-PLC交互】4.DLL读取WINCC内部变量
【傻瓜级JS-DLL-WINCC-PLC交互】4.DLL读取WINCC内部变量
814 0
|
存储 SQL 运维
淘菜菜 (一):基于Flink和Hologres的实时数仓架构升级之路
淘菜菜 (一):基于Flink和Hologres的实时数仓架构升级之路
3336 0
淘菜菜 (一):基于Flink和Hologres的实时数仓架构升级之路