Go语言开发中Json、Xml数据的编码和解析
一、Json数据的解析和编码
在开发过程中我们常常需要对数据进行编码和解析
import "encoding/json"
这个包包实现了json对象的编解码,参见RFC 4627。Json对象和go类型的映射关系请参见Marshal和Unmarshal函数的文档。可在官方文档上面参考官方文档
1)json解析
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
ID int
Name string
Sex string
Course []string
}
func main() {
EncodeStruct()
DecodeJsonString()
}
//将一个对象编码成json字符串
func EncodeStruct() {
student := Student{
ID: 14343466,
Name: "wangbiao",
Sex: "M",
Course: []string{"English", "Math", "Chinese"},
}
b, err := json.Marshal(student)
if err != nil {
fmt.Println("error:", err)
}
fmt.Println(string(b))
}
//将json字符串解码成json字符串
func DecodeJsonString() {
var jsonBody = []byte(`{"ID":14343466,"Name":"wangbiao","Sex":"M","Course":["English","Math","Chinese"]}`)
var student1 = Student{}
err := json.Unmarshal(jsonBody, &student1)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(student1)
fmt.Println("studentName:", student1.Name)
fmt.Println("studentId:", student1.ID)
fmt.Println("studentSex:", student1.Sex)
fmt.Println("studentCourse:", student1.Course)
}
2)json生成
针对JSON的输出,我们在定义struct tag的时候需要注意的几点是:
字段的tag是"-",那么这个字段不会输出到JSON
tag中带有自定义名称,那么这个自定义名称会出现在JSON的字段名中,例如上面例子中serverName
tag中如果带有"omitempty"选项,那么如果该字段值为空,就不会输出到JSON串中
如果字段类型是bool, string, int, int64等,而tag中带有",string"选项,那么这个字段在输出到JSON的时候会把该字段对应的值转换成JSON字符串
type Server struct {
// ID 不会导出到JSON中
ID int `json:"-"`
// ServerName 的值会进行二次JSON编码
ServerName string `json:"serverName"`
ServerName2 string `json:"serverName2,string"`
// 如果 ServerIP 为空,则不输出到JSON串中
ServerIP string `json:"serverIP,omitempty"`
}
s := Server {
ID: 3,
ServerName: `Go "1.0" `,
ServerName2: `Go "1.0" `,
ServerIP: ``,
}
b, _ := json.Marshal(s)
os.Stdout.Write(b)
在涉及到orm时候tag
type studentinfo struct {
Id int `pk:"auto"`
Stuname string `orm:"size(20)"`
Stuidentify string `orm:"size(30)"`
Stubirth time.Time
Stuclass string `orm:"size(30)"`
Stumajor string `orm:"size(30)"`
}
output:{"serverName":"Go "1.0" ","serverName2":""Go \"1.0\" ""}
输出结果如下图:
效果图
二、Xml数据解析和编码
现在大多数数据交互都是json,但是有些和第三方公司对接还是喜欢以Xml进行数据交互,例如美团和微信第三方sdk的服务端数据交互即使以xml进行的,因此了解Xml的生成和解析也是很有必要的
xml解析基本遵循以下原则:
如果v是 array或者slice,那么输出每一个元素,类似value
如果v是指针,那么会Marshal指针指向的内容,如果指针为空,什么都不输出
如果v是interface,那么就处理interface所包含的数据
如果v是其他数据类型,就会输出这个数据类型所拥有的字段信息
生成的XML文件中的element的名字又是根据什么决定的呢?元素名按照如下优先级从struct中获取:
如果v是struct,XMLName的tag中定义的名称
类型为xml.Name的名叫XMLName的字段的值
通过struct中字段的tag来获取
通过struct的字段名用来获取
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,例如如下代码就会输出
1)xml解析:
type Students struct {
XMLName xml.Name `xml:"students"`
Version string `xml:"version,attr"`
Stus []Student `xml:"student"`
}
type Student struct {
StudentID int `xml:"studentid"`
Name string `xml:"studentname"`
Address string `xml:"address"`
School string `xml:"school"`
Age int `xml:"age"`
Sex int `xml:"sex"`
}
func CreateStudentXml() {
stus := &Students{}
stus.Version = "1"
stus.Stus = append(stus.Stus, Student{
StudentID: 3782378,
Name: "江华",
Address: "zhongguo guangzhou",
School: "TaiAn Schlool",
Age: 34,
Sex: 0,
})
stus.Stus = append(stus.Stus, Student{
StudentID: 3782379,
Name: "小歪子Go",
Address: "zhongguo guangzhou",
School: "ShiPai Schlool",
Age: 30,
Sex: 1,
})
out, err := xml.MarshalIndent(stus, "", "")
if err != nil {
fmt.Printf("error:%v\n", err)
} else {
// os.Stdout.Write([]byte(xml.Header))
// os.Stdout.Write(out)
fmt.Println("xxp")
fmt.Println(`<?xml version="1.0" encoding="UTF-8"?>` + "\n" + string(out))
}
}
output:
<?xml version="1.0" encoding="utf-8"?>
<students version="1">
<student>
<studentid>3782378</studentid>
<studentname>江华</studentname>
<address>zhongguo guangzhou</address>
<school>TaiAn Schlool</school>
<age>34</age>
<sex>0</sex>
</student>
<student>
<studentid>3782379</studentid>
<studentname>小歪子Go</studentname>
<address>zhongguo guangzhou</address>
<school>ShiPai Schlool</school>
<age>30</age>
<sex>1</sex>
</student>
</students>
2)xml解析成student
func CreatStudentFromXml() {
stus := Students{}
datas := []byte(string(`<?xml version="1.0" encoding="UTF-8"?>
<students version="1"><student><studentid>3782378</studentid><studentname>江华</studentname><address>zhongguo guangzhou</address><school>TaiAn Schlool</school><age>34</age><sex>0</sex></student><student><studentid>3782379</studentid><studentname>小歪子Go</studentname><address>zhongguo guangzhou</address><school>ShiPai Schlool</school><age>30</age><sex>1</sex></student></students>
`))
err := xml.Unmarshal(datas, &stus)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(stus)
}
}
output:{{ students} 1 [{3782378 江华 zhongguo guangzhou TaiAn Schlool 34 0} {3782379 小歪子Go zhongguo guangzhou ShiPai Schlool 30 1}]}
参考文档
在Go语言中使用JSON