golang xml和json的解析与生成

golang中解析xml时我们通常会创建与之对应的结构体,一层层嵌套,完成复杂的xml解析。

package main;

import (
	"encoding/xml"
	"fmt"
)

//我们通过定义一个结构体,来解析xml
//注意,结构体中的字段必须是可导出的
type Books struct {
	//如果有类型为xml.Name的XMLName字段,则解析时会保存元素名到该字段
	XMLName xml.Name `xml:"books"`;
	//定义的字段中包含,attr,则解析时会把对应字段的属性值赋给该字段
	Nums int `xml:"nums,attr"`;
	//定义的字段名含有xml中元素名,则解析时会把该元素值赋给该字段
	Book []Book `xml:"book"`;
	//字段类型为string或[]byte,并且包含,innerxml,则解析时会把此字段对应的元素内所有原始xml累加到字段上
	Data string `xml:",innerxml"`;
	//字段定义包含-,则解析时不会为该字段匹配任何数据
	Tmp int `xml:"-"`;
}

type Book struct {
	XMLName xml.Name `xml:"book"`;
	Name    string   `xml:"name,attr"`;
	Author  string   `xml:"author"`;
	Time    string   `xml:"time"`;
	//字段定义如a>b>c,这样,解析时会从xml当前节点向下寻找元素并将值赋给该字段
	Types []string `xml:"types>type"`;
	//字段定义有,any,则解析时如果xml元素没有与任何字段匹配,那么这个元素就会映射到该字段
	Test string `xml:",any"`;
}

func main() {
	//xml数据字符串
	data := `<?xml version="1.0" encoding="utf-8"?>
			<books nums="2">
				<book name="思想">
					<author>小张</author>
					<time>2018年1月20日</time>
					<types>
						<type>教育</type>
						<type>历史</type>
					</types>
					<test>我是多余的</test>
				</book>
				<book name="政治">
					<author>小王</author>
					<time>2018年1月20日</time>
					<types>
						<type>科学</type>
						<type>人文</type>
					</types>
					<test>我是多余的</test>
				</book>
			</books>`;

	//创建一个Books对象
	bs := Books{};
	//把xml数据解析成bs对象
	xml.Unmarshal([]byte(data),&bs);
	//打印bs对象中数据
	fmt.Println(bs.XMLName);
	fmt.Println(bs.Nums);
	fmt.Println(bs.Tmp);
	//循环打印Book
	for _,v := range bs.Book {
		fmt.Println(v.XMLName);
		fmt.Println(v.Name);
		fmt.Println(v.Author);
		fmt.Println(v.Time);
		fmt.Println(v.Types);
		fmt.Println(v.Test);
	}
}

反之,通过创建结构体对象,生成xml数据

package main;

import (
	"encoding/xml"
	"fmt"
)

//注意,结构体中的字段必须是可导出的
type Books struct {
	XMLName xml.Name `xml:"books"`;
	Nums    int      `xml:"nums,attr"`;
	Book    []Book   `xml:"book"`;
}

type Book struct {
	XMLName xml.Name `xml:"book"`;
	Name    string   `xml:"name,attr"`;
	Author  string   `xml:"author"`;
	Time    string   `xml:"time"`;
}

func main() {
	bs := Books{Nums: 666};
	//通过append添加book数据
	bs.Book = append(bs.Book,Book{Name: "小红",Author: "阿三",Time: "2018年6月3日"});
	bs.Book = append(bs.Book,Book{Name: "小绿",Author: "阿四",Time: "2018年6月5日"});
	//通过MarshalIndent,让xml数据输出好看点
	data,_ := xml.MarshalIndent(&bs,"","  ");
	fmt.Println(string(data));
}

  

json数据的解析,很多时候我们并不知道json的具体结构,这就需要我们灵活使用interface{}和类型断言来进行解析。

package main;

import (
	"encoding/json"
	"fmt"
)

//创建一个结构体,用来解析json
//注意结构体中字段必须是可导出的
type People struct {
	Name string;
	Age  int;
	Sex  string;
	Love []string;
}

func main() {
	//这是一串json数据
	//golang中json中的字段名也要加双引号,不然无法解析
	data := `{
				"name": "小张","age": 27,"sex": "男","love": ["看书","旅游","健身"]
			 }`;
	//我们创建一个people对象
	p := People{};
	//解析到结构
	json.Unmarshal([]byte(data),&p);
	fmt.Printf("%#v\n",p);
	fmt.Println(p.Name);
	fmt.Println(p.Age);
	fmt.Println(p.Sex);
	fmt.Println(p.Love);

	//解析到一个interface{}
	//golang中通过map[string]interface{}或[]interface{}来解析任意的对象和数组
	var p2 interface{};
	json.Unmarshal([]byte(data),&p2);
	fmt.Printf("%#v\n",p2);

	//我们通过类型断言来访问数据
	//先将p2转换成map[string]interface{}类型
	p3 := p2.(map[string]interface{});
	//然后遍历
	for i,v := range p3 {
		switch vv := v.(type) {
		case string:
			fmt.Println(i,"string: ",vv);
		case int:
			fmt.Println(i,"int: ",vv);
		case []interface{}:
			//通过interface{}和类型断言,我们可以解析未知结构的json
			for _,vl := range vv {
				fmt.Println(i,"[]interface{}: ",vl);
			}
		}
	}
}

通过结构体对象生成json数据

package main;

import (
	"encoding/json"
	"fmt"
)

//注意结构体的字段必须是可导出的
type Book struct {
	//"name"表示指定json输出的名字
	Name   string `json:"name"`;
	Author string `json:"author"`;
	Time   string `json:"time"`;
	//,string表示字段输出时会把字段值转成字符串
	Nums int `json:"nums,string"`;
	//字段定义中有-,表示该字段不会输出到json
	Temp string `json:"-"`;
	//,omitempty表示如果字段值为空,不会输出到json
	Empty string `json:"empty,omitempty"`;
}

type BookList struct {
	Books []Book `json:"books"`;
}

func main() {
	bl := BookList{
		Books: []Book{
			Book{Name: "一本书",Author: "小张",Time: "2018年1月20日",Nums: 233,Temp: "临时",Empty: ""},Book{Name: "二本书",Author: "小王",Time: "2018年1月12日",Empty: "不为空"},},}
	data,_ := json.MarshalIndent(bl,"  ");
	fmt.Println(string(data));
}

  

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考
这篇文章主要介绍“怎么以正确的方式替换Go语言程序自身”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希
本文小编为大家详细介绍“Go语言中除法运算的效率怎么提高”,内容详细,步骤清晰,细节处理妥当,希望这篇“Go语言中除法运算的效率怎么提高”文章能帮助大家解...
本文小编为大家详细介绍“Go语言中的next()方法怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Go语言中的next()方法怎么使用”文章能帮助大家解决疑...
这篇文章主要介绍了Go语言中slice的反转方法怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go语言中slice的反转方法怎...
这篇文章主要介绍“怎么使用Go语言实现数据转发功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Go语
这篇文章主要讲解了“Go语言中怎么实现代码跳转”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究
这篇文章主要讲解了“Go语言如何多开协程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言如何多开协...