GoWeb——处理XML文件

2023-11-12

处理XML文件

XML(eXtensible Markup Language,可扩展标记语言)是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据。

1、解析XML文件

Go语言提供了xml包用于解析和生成XML。xml包中提供一个名为Unmarshal()函数来解析XML,该函数的定义如下:

func Unmarshal(data []byte,v interface{]) error

其中,data接收的是XML数据流,v是需要输出的结构(如将其定义为interface,则可以把XML转换为任意的格式)。Go在解析XML中的数据时,最主要的是处理XML到结构体的转换问题,结构体和XML都有类似树结构的特征。Go解析XML到结构体会遵循以下原则:

  • 如果结构体的一个字段是string或者[]byte类型,且它的tag含有“,innerxml’”,则Unmarshal()函数会将此字段所对应的元素内所有内嵌的原始xml累加到该结构体中对应的字段中。
  • 如果在结构体中有一个被称为XMLName,且类型为xml.Name的字段,则在解析时会保存这个元素的名字到该结构体中对应的字段中。
  • 如果在某个结构体字段的tag定义中含有XML结构中元素的名称,则解析时会把相应的元素值赋值给该结构体中对应的字段。
  • 如果在某个结构体字段的tag定义中含有“,attr”,则解析时会将该结构所对应的元素与字段同名的属性的值赋值给该结构体中对应的字段。
  • 如果某个结构体字段的tag定形了形如“c>d>e”的字符串,则解析时会将xml结构c下面的d下面的元素的值赋值给该结构体中对应的字段。
  • 如果某个结构体字段的tag定义了“-”,则不会为该字段解析匹配任何xml数据。
  • 如果结构体字段后面的tag定义了“,any”,且它的子元素不满足其他的规则,则匹配到这个字段。
  • 如果某个XML元素包含一条或者多条注释,则这些注释将被累加到第1个tag含有“,comments”的字段中。这个字段的类型可能是[]byte或string。如果没有这样的字段,则注释会被抛弃。
  1. 新建一个名为default.xml的配置文件,其内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<config>
    <smtpServer>smtp.163.com</smtpServer>
    <smtpPort>25</smtpPort>
    <sender>test@163.com</sender>
    <senderPassword>123456</senderPassword>
    <receivers flag="true">
        <user>tom</user>
        <user>jerry</user>
    </receivers>
</config>

以上代码是一个xml配置文件,该配置以config为root标签,包含xml属性文本(比如smtpServer标签)、嵌套xml(receivers标签)、xml attribute属性文本(receivers标签的flag),以及类似数组的多行配置(user标签)。数据类型有字符串和数字两种类型。

  1. 读取default.xml配置文件,并解析打印到命令行终端
import (
	"encoding/xml"
	"fmt"
	"io"
	"log"
	"os"
)

type EmailConfig struct {
	XMLName        xml.Name       `xml:"config"`
	SmtpServer     string         `xml:"smtpServer"`
	SmtpPort       int            `xml:"smtpPort"`
	Sender         string         `xml:"sender"`
	SenderPassword string         `xml:"senderPassword"`
	Receivers      EmailReceivers `xml:"receivers"`
}

type EmailReceivers struct {
	Flag string   `xml:"flag,attr"`
	User []string `xml:"user"`
}

func main() {
	file, err := os.Open("default.xml")
	if err != nil {
		log.Panicln(err)
	}
	data, err := io.ReadAll(file)
	if err != nil {
		log.Panicln(err)
	}
	v := EmailConfig{}
	err = xml.Unmarshal(data, &v)
	if err != nil {
		log.Panicln(err)
	}
	fmt.Println(v)
	fmt.Println("Name is:", v.XMLName)
	fmt.Println("SmtpServer is:", v.SmtpServer)
	fmt.Println("Sender is:", v.Sender)
	fmt.Println("SenderPasswd is:", v.SenderPassword)
	fmt.Println("Reveivers.Flag is:", v.Receivers.Flag)
	for i, ele := range v.Receivers.User {
		fmt.Println(i, ele)
	}
}
{{ config} smtp.163.com 25 test@163.com 123456 {true [tom jerry]}}
Name is: { config}
SmtpServer is: smtp.163.com
Sender is: test@163.com
SenderPasswd is: 123456
Reveivers.Flag is: true
0 tom
1 jerry

2、生成XML文件

需要用到xml包中的Marshal()和Marshallndent()这两个函数。这两个函数主要的区别是:

  • Marshallndent()函数会增加前缀和缩进
  • Marshal()则不会

这两个函数的定义如下:

func Marshal(v interface())([]byte,error)
func MarshalIndent (v interface(),prefix,indent string)([]byte,error)

两个函数的第1个参数都用来生成XML文件的结构定义数据,都是返回生成的XML文件。生成XML文件的示例如下。

import (
	"encoding/xml"
	"log"
	"os"
)

type Languages struct {
	XMLName xml.Name   `xml:"languages"`
	Version string     `xml:"version,attr"`
	Lang    []Language `xml:"language"`
}

type Language struct {
	Name string `xml:"name"`
	Site string `xml:"site"`
}

func main() {
	v := &Languages{Version: "2"}
	v.Lang = append(v.Lang, Language{"JAVA", "https://www.java.com/"})
	v.Lang = append(v.Lang, Language{"Go", "https://golang.org/"})
	output, err := xml.MarshalIndent(v, " ", " ")
	if err != nil {
		log.Panicln(err)
	}
	file, _ := os.Create("languages.xml")
	file.Write([]byte(xml.Header))
	file.Write(output)
}

生成的languages.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
 <languages version="2">
  <language>
   <name>JAVA</name>
   <site>https://www.java.com/</site>
  </language>
  <language>
   <name>Go</name>
   <site>https://golang.org/</site>
  </language>
 </languages>

下面再分析一下Go语言代码。xml.Marshallndent()函数和xml.Marshal()函数输出的信息都是不带XML头的。为了生成正确的XML文件,需要使用XML包预定义的Header变量,所以需要加上file.Write([byte(xml.Header)这行代码。
Marshal()函数接收的参数v是interface}类型的,即它可以接受任意类型的参数。

xml包会根据如下规则来生成相应的XML文件:

  • 如果v是array或者slice,则输出每一个元素,类似value。
  • 如果v是指针,则会输出Marshal指针指向的内容。如果指针为空,则什么都不输出。
  • 如果v是interface,则处理interface所包含的数据。
  • 如果v是其他数据类型,则输出这个数据类型所拥有的字段信息。

元素名按照如下优先级从结构体中获取:

  • 如果v是结构体,则XMLName的tag中定义的名称优先被获取。
  • 类型为xml.Name、名为XMLName的字段的值被优先被获取。
  • 通过结构体中字段的tag来获取。
  • 通过结构体的字段名来获取。
  • marshall的类型名称。

设置结构体中字段的tag信息,以控制最终XML文件的生成:

  • XMLName不会被输出。
  • tag中含有“-”的字段不会被输出。
  • 如果tag中含有“name,attr”,则会以name作为属性名,以字段值作为值输出为这个XML元素的属性。
  • 如果tag中含有“,att”,则会以这个结构体的字段名作为属性名输出为XML元素的属性,类似上一条,只是这个name默认是字段名了。
  • 如果tag中含有“,chardata”,则输出为XML元素的character data,而非element.
  • 如果tag中含有“,innerxml’”,则它会被原样输出,而不会进行常规的编码过程。
  • 如果tag中含有“,comment’”,则它将被当作XML元素的注释来输出,而不会进行常规的编码过程。字段值中不能含有“–”字符串。
  • 如果tag中含有“omitempty”,若该字段的值为空值,则该字段就不会被输出到XML中。其中空值包括false,0,nil指针,nil接口,任何长度为O的array、slice、map或
    string.
  • 如果tag中含有“c>d>e”,则会循环输出这3个元素,其中c包含d,d包含e。

例如如下代码:

Ip string `xml:"address>ip"`
Port string `xml:"address>port"`


//生成结果
<address>
	<ip>127.0.0.1</ip>
	<port>8080</port>
</address>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GoWeb——处理XML文件 的相关文章

随机推荐

  • HUE+LDAP+HIVE,报错:PLAIN auth failed: Error validating LDAP user

    我已经为hue集成了ldap 本次为hive集成ldap认证之后 登录hue后 在hive editor中执行sql语句报如下错误 Bad status 3 PLAIN auth failed Error validating LDAP u
  • Web服务(04)——LAMP的简介与搭建+DISCUZ论坛

    文章目录 LAMP的简介与搭建 DISCUZ论坛 前言 一 LAMP的简介 二 Apache服务 三 LAMP服务的搭建 1 编译安装apache服务 2 编译安装MYSQL服务 3 编译安装PHP服务 四 搭建DISCUZ论坛 总结 LA
  • Datax 的基本操作

    1 Datax 简介 DataX 是一个异构数据源离线同步工具 致力于实现包括关系型数据库 MySQL Oracle等 HDFS Hive ODPS HBase FTP等各种异构数据源之间稳定高效的数据同步功能 开源地址 https git
  • 【LeetCode训练营 189】轮转数组详解

    博客内容 LeetCode训练营 189 轮转数组详解 作 者 陈大大陈 个人简介 一个正在努力学技术的准前端 专注基础和实战分享 欢迎私信 欢迎大家 这里是CSDN 我总结知识和写笔记的地方 喜欢的话请三连 有问题请私信 目录 暴力法 辅
  • 一文看尽深度学习中的15种损失函数

    转自 https zhuanlan zhihu com p 377799012 在机器学习中 损失函数是代价函数的一部分 而代价函数则是目标函数的一种类型 1 Loss function 即损失函数 用于定义单个训练样本与真实值之间的误差
  • 解决PL/SQL 8 ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务的问题

    今天晚上貌似遇到的ORACLE11G问题特别多 不过还好 几经尝试 都在网上找到了答案并解决了这些问题 留个备份 PL SQL Developer工具在连oracle11g的时候 碰到了这个问题 ORA 12514 TNS 监听程序当前无法
  • 【C语言数据结构】带头节点与不带头节点的单链表头插法对比

    前言 近期在学习STM32代码框架的过程中 老师使用链表来注册设备 发现使用了不带头节点的单链表 注册时使用头插法 之前在本专题整理学习过带头节点的单链表 因此本文整理对比一下两种方式的头插法区别 具体实现在次 重点在于用以理解两种思路 以
  • Apikit 自学日记:API 异常监控-创建 API 监控

    如何在apikit中 创建 API 监控呢 创建并开启监控API 一 手动创建监控API Eolink API 网络监控平台支持从 Eolink API Management API管理产品 中导入API信息 或者手动创建监控API 进入A
  • (杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(3)

    1005 Out of Control 先将序列a升序 然后离散化 比如说序列a为1000 1000 500 200 10 然后升序后为10 200 500 1000 1000 映射到从1开始的数 为1 2 3 4 4 此即为前缀最大值序列
  • Flask 学习-70.Flask-RESTX 注册接口实例

    前言 注册接口主要是密码需要加密 用到werkzeug security 模块的2个方法generate password hash check password hash 数据库操作用到Flask SQLAlchemy 相关的基础配置就不
  • 如何利用路由器连接wifi并将wifi网络分发出去

    有时候 我们的wifi网络设置了最大连接数 该数字小于我们的需求数 我们可以考虑利用路由器来进一步分发wifi网络 下面以tp link的产品为例介绍如何分发网络 1 开启路由器 让其发出广播信号 2 使用电脑无线功能连接该路由器 登录路由
  • Vue项目this.$router.push()找不到push问题

    在使用Vue cli开发项目时 我喜欢使用Es6语法 但在使用语法跳路由时却会受到报错 因为Es6的箭头函数的this指向的是最近的一个this 而不是全局的 所以会造成找不到路由方法的问题 解决方法 使用传统语法 XXX function
  • 7-4 多态练习-计算面积

    定义三个类 父类 抽象类 GeometricObject代表几何形状 子类Circle代表圆形 子类Rectangle代表矩形 具体属性和方法如下 父类 抽象类 GeometricObject 属性 private String color
  • 华硕主板BIOS设置虚拟化技(virtualization technology)

    华硕主板BIOS设置虚拟化技 virtualization technology 背景 环境介绍 win安装docker介绍 bios虚拟技术是否开启检查 虚拟技术开启 打开bios设置 虚拟技术设置 参考文献 背景 从2013开始 doc
  • A,NS,cname,forward,txt,aaaa记录讲解

    最近刚好处理DNS问题比较多 对DNS复习一下基础知识 在DNS域名解析中 记录存在很多种 例如主要的A记录 NS记录 CNAME记录 FORWARD记录 还有X记录等等 现在就对它们的区别与联系做总结 1 A记录 A记录又称IP指向 用户
  • 前端面试题总结带答案(持续更新)

    Vue面试题 1 什么是 vue 生命周期 Vue 实例从创建到销毁的过程 就是生命周期 也就是从开始创建 初始化数据 编译模板 挂载Dom 渲染 更新 渲染 卸载等一系列过程 我们称这是 Vue 的生命周期 它可以总共分为8个阶段 创建前
  • 音乐铃声解析提取API接口

    接口地址 https api hackeus cn api kgring 请求协议 HTTP HTTPS 请求方式 GET POST 返回格式 JSON 请求示例 https api hackeus cn api kgring api ke
  • intellij IDEA中我一运行程序,就提示我edit configuration

    因为你直接使用open来打开别人的项目 所以有问题 正确方法 重新打开intellij界面 使用import来导入别人的项目
  • [UnityShader入门精要读书笔记]06.顶点/片元着色器基本结构

    Unity Shader基本结构包含Shader Properties SubShader FallBack等语义块 结构如下 Shader MyShaderName Properties 属性 SubShader 针对显卡A的SubSha
  • GoWeb——处理XML文件

    目录 处理XML文件 1 解析XML文件 2 生成XML文件 处理XML文件 XML eXtensible Markup Language 可扩展标记语言 是一种数据表示格式 可以描述非常复杂的数据结构 常用于传输和存储数据 1 解析XML