xml和json转换为结构体

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日", Nums: 233, Temp: "临时", Empty: "不为空"},
        },
    }
    data, _ := json.MarshalIndent(bl, "", "  ");
    fmt.Println(string(data));
}

xml和json转换为结构体

上一篇:C语言结构体初始化的四种方法 【转载】


下一篇:小程序 new Date(2019-03-01 00:00:00) 返回对象null