The official account of WeChat: the story of operation and development.
Parsing and generating yaml files
YAML (YAML is not a markup language) is a human readable data serialization language. It is usually used for configuration files, but it is also used for data storage or transmission.
YAML itself supports three basic data types: scalar (such as string, integer and floating point), list and mapping (Dictionary / hash).
We use the yaml.v3 package to parse the yaml file
go get gopkg.in/yaml.v3
Parse yaml
func Unmarshal(in []byte, out interface{}) (err error)
We use Unmarshal to parse yaml
yaml file contents are as follows:
- name: wanger age: 24 address: beijing hobby: - literature - social - name: Brother Dong age: 30 address: chengdu hobby: - basketball - guitar - name: Huazi age: 27 address: shenzhen hobby: - Glory of Kings - name: Jock age: 29 address: chongqing hobby: - read - Glory of Kings - name: Miss Xia age: 27 address: chengdu hobby: - Eat and drink - name: Jiang Zong age: 25 address: shanghai hobby: - talkshow - name: Zheng Ge age: 30 address: beijing hobby: - read - Repeater
Read test.yaml
package main import ( "fmt" "gopkg.in/yaml.v2" "io/ioutil" "gopkg.in/yaml.v3" "log" ) type Users struct { Name string `yaml:"name"` Age int8 `yaml:"age"` Address string `yaml:"address"` Hobby []string `yaml:"hobby"` } func main() { file, err := ioutil.ReadFile("test.yaml") if err != nil { log.Fatal(err) } var data [7]Users err2 := yaml.Unmarshal(file, &data) if err2 != nil { log.Fatal(err2) } for _, v := range data { fmt.Println(v) } }
The output is as follows
{wanger 24 beijing [literature social]} {Dongge 30 chengdu [basketball guitar]} {Huazi 27 shenzhen [Glory of Kings]} {Jock 29 chongqing [Read the glory of the king]} {Miss Xia 27 chengdu [Eat and drink]} {Jiang Zong 25 shanghai [Fishing music food wine talkshow]} {Zheng Ge 30 beijing [Reading repeater]}
Generate yaml
func Marshal(in interface{}) (out []byte, err error)
Let's use Marshal to generate yaml and generate a yaml file about our team information
You can customize the key name of the output yaml file by defining the structure yaml label
package main import ( "fmt" "gopkg.in/yaml.v3" ) type Users struct { Name string `yaml:"name"` Age int8 `yaml:"age"` Address string `yaml:"address"` Hobby []string `yaml:"hobby"` } func main() { wanger := Users{ Name: "wanger", Age: 24, Address: "beijing", Hobby: []string{"literature", "social"}, } dongdong := Users{ Name: "Brother Dong", Age: 30, Address: "chengdu", Hobby: []string{"basketball", "guitar"}, } xialaoshi := Users{ Name: "Miss Xia", Age: 29, Address: "chengdu", Hobby: []string{"Eat and drink"}, } huazai := Users{ Name: "Huazi", Age: 28, Address: "shenzhen", Hobby: []string{"Glory of Kings"}, } qiaoke := Users{ Name: "Jock", Age: 30, Address: "chongqing", Hobby: []string{"read", "Glory of Kings"}, } jiangzong := Users{ Name: "Jiang Zong", Age: 25, Address: "shanghai", Hobby: []string{"go fishing","music","delicious food","Alcohol"}, } zhengge := Users{ Name: "Zheng Ge", Age: 30, Address: "beijing", Hobby: []string{"read", "Repeater"}, } userlist:=[7]Users{wanger,dongdong,huazai,qiaoke,xialaoshi,jiangzong,zhengge} yamlData, err := yaml.Marshal(&userlist) if err != nil { fmt.Printf("Error while Marshaling. %v", err) } fmt.Println(string(yamlData)) fileName := "test.yaml" err = ioutil.WriteFile(fileName, yamlData, 0644) if err != nil { panic("Unable to write data into the file") } }
The generated yaml information is as follows
- name: wanger age: 24 address: beijing hobby: - literature - social - name: Brother Dong age: 30 address: chengdu hobby: - basketball - guitar - name: Huazi age: 27 address: shenzhen hobby: - Glory of Kings - name: Jock age: 29 address: chongqing hobby: - read - Glory of Kings - name: Miss Xia age: 27 address: chengdu hobby: - Eat and drink - name: Jiang Zong age: 25 address: shanghai hobby: - go fishing - music - delicious food - Alcohol - name: Zheng Ge age: 30 address: beijing hobby: - read - Repeater
Parsing and generating json files
We use encoding/json standard library package to parse and generate json files
Reading and parsing json files
func Unmarshal(data []byte, v interface{}) error
I define a user.json file here
{ "users": [ { "name": "wanger", "address": "beijing", "age": 24, "social": { "mobile": "111111111", "email": "wanger@163.com" } }, { "name": "dongdong", "address": "chengdu", "age": 30, "social": { "mobile": "2222222222222222", "emial": "dongdong@163.com" } }, { "name": "Miss Xia", "address": "chengdu", "age": 29, "social": { "mobile": "2232222222222222", "emial": "xialaoshi@163.com" } }, { "name": "Zheng Ge", "address": "beijing", "age": 30, "social": { "mobile": "12222211111", "email": "zhengge@163.com" } }, { "name": "Jiang Zong", "address": "shanghai", "age": 25, "social": { "mobile": "111122211", "email": "jaingzong@163.com" } }, { "name": "Jock", "address": "chongqing", "age": 30, "social": { "mobile": "11333331111111", "email": "qiaoke@163.com" } }, { "name": "Huazi", "address": "shenzhen", "age": 28, "social": { "mobile": "113311111", "email": "huazai@163.com" } } ] }
Read the user.json file
package main import ( "encoding/json" "fmt" "io/ioutil" "os" "strconv" ) func main() { jsonFile,err:=os.Open("user.json") if err != nil { fmt.Println(err) } fmt.Println("Successfully Opened users.json") defer jsonFile.Close() byteValue,_:=ioutil.ReadAll(jsonFile) var users Users json.Unmarshal(byteValue,&users) for i :=0;i<len(users.Users);i++ { fmt.Println("User Type: "+ users.Users[i].Address) fmt.Println("User Age: "+strconv.Itoa(users.Users[i].Age)) fmt.Println("User Name: "+users.Users[i].Name) fmt.Println("User Email: "+users.Users[i].Social.Email) } var result Users json.Unmarshal(byteValue,&result) } type Users struct { Users []User `json:"users"` } type User struct { Name string `json:"name"` Address string `json:"address"` Age int `json:"Age"` Social Social `json:"social"` } type Social struct { Mobile string `json:"mobile"` Email string `json:"email"` }
The output results are as follows
Successfully Opened users.json User Type: beijing User Age: 24 User Name: wanger User Email: wanger@163.com User Type: chengdu User Age: 30 User Name: dongdong User Email: User Type: chengdu User Age: 28 User Name: Miss Xia User Email: User Type: beijing User Age: 30 User Name: Zheng Ge User Email: zhengge@163.com User Type: shanghai User Age: 25 User Name: Jiang Zong User Email: jaingzong@163.com User Type: chongqing User Age: 29 User Name: Jock User Email: qiaoke@163.com User Type: shenzhen User Age: 28 User Name: Huazi User Email: huazai@163.com
Of course, sometimes we may not know the json data structure to be read, so there is no way to predefine the structure, so we can use the * * map[string]interface {} * * type to resolve json.
var result map[string]interface{} err = json.Unmarshal(byteValue, &result) fmt.Printf("%+v\n", result)
The output information is as follows:
map[users:[map[address:beijing age:24 name:wanger social:map[email:wanger@163.com mobile:111111]] map[address:chengdu age:30 name:dongdong social:map[emial:dongdong@163.com mobil222222222222222]] map[address:chengdu age:28 name:Miss Xia social:map[emial:xialaoshi@163.cmobile:2232222222222222]] map[address:beijing age:30 name:Zheng Ge social:map[email:zhengge@1com mobile:12222211111]] map[address:shanghai age:25 name:Jiang Zong social:map[email:jaingzong3.com mobile:111122211]] map[address:chongqing age:29 name:Jock social:map[email:qiaoke@1com mobile:11333331111111]] map[address:shenzhen age:28 name:Huazi social:map[email:huazai3.com mobile:113311111]]]]
Generate json file
func Marshal(v interface{}) ([]byte, error)
package main import ( "encoding/json" "fmt" "io/ioutil" ) func main() { wanger:=User{Address:"beijing",Name:"wanger",Age:24,Social:Social{Email:"wanger@163.com",Mobile:"111111111111"}} huazi:=User{Address:"shenzhen",Name:"huazai",Age:28,Social:Social{Email:"huazai@163.com",Mobile:"111122211111"}} qiaoke:=User{Address:"chongqing",Name:"qiaoke",Age:30,Social:Social{Email:"qiaoke@163.com",Mobile:"13332211111"}} xialaoshi:=User{Address:"chengdu",Name:"Miss Xia",Age:29,Social:Social{Email:"xialaoshi@163.com",Mobile:"11144445411111"}} jiangzong:=User{Address:"shanghai",Name:"Jiang Zong",Age:25,Social:Social{Email:"jiangzong@163.com",Mobile:"111222445211111"}} dongdong:=User{Address:"chengdu",Name:"Brother Dong",Age:30,Social:Social{Email:"dongdong@163.com",Mobile:"1155555211111"}} zhengge:=User{Address:"beijing",Name:"Zheng Ge",Age:24,Social:Social{Email:"zhengge@163.com",Mobile:"1112224566211111"}} result:=Users{Users: []User{wanger,huazi,jiangzong,xialaoshi,qiaoke,dongdong,zhengge}} bytearray,err:=json.Marshal(result) if err!=nil { fmt.Println(err) } fmt.Println(string(bytearray)) fileName := "user.json" err = ioutil.WriteFile(fileName, bytearray, 0644) if err != nil { panic("Unable to write data into the file") } } type Users struct { Users []User `json:"users"` } type User struct { Name string `json:"name"` Address string `json:"address"` Age int `json:"Age"` Social Social `json:"social"` } type Social struct { Mobile string `json:"mobile"` Email string `json:"email"` }
The output is as follows
{"users":[{"name":"wanger","address":"beijing","Age":24,"social":{"mobile":"111111111111","email":"wanger@163.com"}},{"name":"huazai","address":"shenzhen","Age":28,"social":{"mobile":"111122211111","email":"huazai@163.com"}},{"name":"Jiang Zong","address":"shanghai","Age":25,"social":{"mobile":"111222445211111","email":"jiangzong@163.com"}},{"name":"Miss Xia","address":"chengdu","Age":29,"social":{"mobile":"11144445411111","email":"xialaoshi@163.com"}},{"name":"qiaoke","address":"chongqing","Age":30,"social":{"mobile":"13332211111","email":"qiaoke@163.com"}},{"name":"Brother Dong","address":"chengdu","Age":30,"social":{"mobile":"1155555211111","email":"dongdong@163.com"}},{"name":"Zheng Ge","address":"beijing","Age":24,"social":{"mobile":"1112224566211111","email":"zhengge@163.com"}}]}
It can be seen that the json output above is not very beautiful. You can use the more readable function * * json.MarshalIndent() * * function. MarshalIndent() can define the prefix and indentation of the output
bytearray,err:=json.MarshalIndent(result,""," ") if err!=nil { fmt.Println(err) } fmt.Println(string(bytearray))
The output is as follows, which looks much better than before
{ "users": [ { "name": "wanger", "address": "beijing", "Age": 24, "social": { "mobile": "111111111111", "email": "wanger@163.com" } }, { "name": "huazai", "address": "shenzhen", "Age": 28, "social": { "mobile": "111122211111", "email": "huazai@163.com" } }, { "name": "Jiang Zong", "address": "shanghai", "Age": 25, "social": { "mobile": "111222445211111", "email": "jiangzong@163.com" } }, { "name": "Miss Xia", "address": "chengdu", "Age": 29, "social": { "mobile": "11144445411111", "email": "xialaoshi@163.com" } }, { "name": "qiaoke", "address": "chongqing", "Age": 30, "social": { "mobile": "13332211111", "email": "qiaoke@163.com" } }, { "name": "Brother Dong", "address": "chengdu", "Age": 30, "social": { "mobile": "1155555211111", "email": "dongdong@163.com" } }, { "name": "Zheng Ge", "address": "beijing", "Age": 24, "social": { "mobile": "1112224566211111", "email": "zhengge@163.com" } } ] }
Parsing and generating xml files
Parsing xml files
func Unmarshal(data []byte, v interface{}) error
Define a user.xml file
<?xml version="1.0" encoding="UTF-8"?> <users> <user address="beijing"> <name>wanger</name> <age>24</age> <social> <email>wanger@163.com</email> <mobile>1233455464</mobile> </social> </user> <user address="chengdu"> <name>Brother Dong</name> <age>30</age> <social> <email>dongge@163.com</email> <mobile>12245555464</mobile> </social> </user> <user address="chengdu"> <name>Miss Xia</name> <age>29</age> <social> <email>xialaoshi@163.com</email> <mobile>12335677464</mobile> </social> </user> <user address="beijing"> <name>Zheng Ge</name> <age>30</age> <social> <email>zhengge@163.com</email> <mobile>12334355464</mobile> </social> </user> <user address="shanghai"> <name>Jiang Zong</name> <age>25</age> <social> <email>jiangzong@163.com</email> <mobile>123565455464</mobile> </social> </user> <user address="chongqing"> <name>Jock</name> <age>29</age> <social> <email>qiaoke@163.com</email> <mobile>124676755464</mobile> </social> </user> <user address="shenzhen"> <name>Huazi</name> <age>28</age> <social> <email>huazai@163.com</email> <mobile>1238655464</mobile> </social> </user> </users>
Parsing xml files
address,attr means that the address field is an XML attribute rather than a nested element.
If the structure has a field of type Name named XMLName, Unmarshal records the element Name in the field.
In order to parse correctly, the xml package of go language requires that all fields in the struct definition must be exportable (i.e. capitalized)
package main import ( "encoding/xml" "fmt" "io/ioutil" "os" ) func main() { xmlFile,err:=os.Open("users.xml") if err!=nil { fmt.Println(err) } fmt.Println("successfully opened users.xml") defer xmlFile.Close() byteValue,_:=ioutil.ReadAll(xmlFile) var users Users xml.Unmarshal(byteValue,&users) for i :=0;i<len(users.Users);i++ { fmt.Println("User Address: "+users.Users[i].Address) fmt.Println("User Name: "+users.Users[i].Name) fmt.Println("Facebook Url: "+users.Users[i].Social.Email) } } type Users struct { XMLName xml.Name `xml:"users"` Users []User `xml:"user"` } type User struct { XMLName xml.Name `xml:"user"` Address string `xml:"address,attr"` Name string `xml:"name"` Social Social `xml:"social"` } type Social struct { XMLName xml.Name `xml:"social"` Mobile string `xml:"mobile"` Email string `xml:"email"` }
The output results are as follows:
successfully opened users.xml User Address: beijing User Name: wanger Facebook Url: wanger@163.com User Address: chengdu User Name: Brother Dong Facebook Url: dongge@163.com User Address: chengdu User Name: Miss Xia Facebook Url: xialaoshi@163.com User Address: beijing User Name: Zheng Ge Facebook Url: zhengge@163.com User Address: shanghai User Name: Jiang Zong Facebook Url: jiangzong@163.com User Address: chongqing User Name: Jock Facebook Url: qiaoke@163.com User Address: shenzhen User Name: Huazi Facebook Url: huazai@163.com
Generate xml file
func Marshal(v interface{}) ([]byte, error) func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
You can use the Marshal() function and MarshalIndent() function, which are also used in the previous json and yaml packages. The difference is that MarshalIndent() can be added
Prefixes and indents look more beautiful. Marshall and Marshall indent process all other data by writing one or more XML elements containing data.
package main import ( "encoding/xml" "fmt" "io/ioutil" ) func main() { wanger:=User{Address:"beijing",Name:"wanger",Age:24,Social:Social{Email:"wanger@163.com",Mobile:"111111111111"}} huazi:=User{Address:"shenzhen",Name:"huazai",Age:28,Social:Social{Email:"huazai@163.com",Mobile:"111122211111"}} qiaoke:=User{Address:"chongqing",Name:"qiaoke",Age:30,Social:Social{Email:"qiaoke@163.com",Mobile:"13332211111"}} xialaoshi:=User{Address:"chengdu",Name:"Miss Xia",Age:29,Social:Social{Email:"xialaoshi@163.com",Mobile:"11144445411111"}} jiangzong:=User{Address:"shanghai",Name:"Jiang Zong",Age:25,Social:Social{Email:"jiangzong@163.com",Mobile:"111222445211111"}} dongdong:=User{Address:"chengdu",Name:"Brother Dong",Age:30,Social:Social{Email:"dongdong@163.com",Mobile:"1155555211111"}} zhengge:=User{Address:"beijing",Name:"Zheng Ge",Age:24,Social:Social{Email:"zhengge@163.com",Mobile:"1112224566211111"}} v:=&Users{Users: []User{wanger,huazi,qiaoke,xialaoshi,zhengge,jiangzong,dongdong}} result, err := xml.MarshalIndent(v, " ", " ") if err != nil { fmt.Printf("error: %v\n", err) } fmt.Println(string(result)) fileName := "users.xml" err = ioutil.WriteFile(fileName, result, 0644) if err != nil { panic("Unable to write data into the file") } } type Users struct { XMLName xml.Name `xml:"users"` Users []User `xml:"user"` } type User struct { XMLName xml.Name `xml:"user"` Age int64 `xml:"age"` Address string `xml:"address,attr"` Name string `xml:"name"` Social Social `xml:"social"` } type Social struct { XMLName xml.Name `xml:"social"` Mobile string `xml:"mobile"` Email string `xml:"email"` }
The output information is as follows
<users> <user address="beijing"> <age>24</age> <name>wanger</name> <social> <mobile>111111111111</mobile> <email>wanger@163.com</email> </social> </user> <user address="shenzhen"> <age>28</age> <name>huazai</name> <social> <mobile>111122211111</mobile> <email>huazai@163.com</email> </social> </user> <user address="chongqing"> <age>30</age> <name>qiaoke</name> <social> <mobile>13332211111</mobile> <email>qiaoke@163.com</email> </social> </user> <user address="chengdu"> <age>29</age> <name>Miss Xia</name> <social> <mobile>11144445411111</mobile> <email>xialaoshi@163.com</email> </social> </user> <user address="beijing"> <age>24</age> <name>Zheng Ge</name> <social> <mobile>1112224566211111</mobile> <email>zhengge@163.com</email> </social> </user> <user address="shanghai"> <age>25</age> <name>Jiang Zong</name> <social> <mobile>111222445211111</mobile> <email>jiangzong@163.com</email> </social> </user> <user address="chengdu"> <age>30</age> <name>Brother Dong</name> <social> <mobile>1155555211111</mobile> <email>dongdong@163.com</email> </social> </user> </users>