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 举报,一经查实,本站将立刻删除。