1. 程式人生 > 其它 >go基礎:xml解析

go基礎:xml解析

技術標籤:goxmlxmlgo

一、簡介

xml是一種進行資料交換和資訊傳遞的一種格式,在web後端開發使用非常普遍,下面介紹go語言解析xml的方法。

二、程式碼

1.將xml解析為物件

<Person>
    <FullName>Grace R. Emlin</FullName>
    <Company>Example Inc.</Company>
    <Email where="home">
        <Addr>[email protected]</Addr
>
</Email> <Email where='work'> <Addr>[email protected]</Addr> </Email> <Group> <Value>Friends</Value> <Value>Squash</Value> </Group> <City>Hanga Roa</City> <State>
Easter Island</State> </Person>

使用xml的Unmarshal進行自動解析

import (
	"encoding/xml"
	"fmt"
)

type Email struct {
		Where string `xml:"where,attr"`
		Addr  string
	}
	type Address struct {
		City, State string
	}
	type Result struct {
		// XMLName xml.Name `xml:"Person"`
Name string `xml:"FullName"` Phone string Email []Email Groups []string `xml:"Group>Value"` Address } type Root struct { XMLName xml.Name `xml:"root"` Res Result `xml:"Person"` } v := Result{Name: "none", Phone: "none"} data := ` <Person> <FullName>Grace R. Emlin</FullName> <Company>Example Inc.</Company> <Email where="home"> <Addr>[email protected]</Addr> </Email> <Email where='work'> <Addr>[email protected]</Addr> </Email> <Group> <Value>Friends</Value> <Value>Squash</Value> </Group> <City>Hanga Roa</City> <State>Easter Island</State> </Person> ` err := xml.Unmarshal([]byte(data), &v) if err != nil { fmt.Printf("error: %v", err) return } // fmt.Printf("XMLName: %#v\n", v.XMLName) fmt.Printf("Name: %q\n", v.Name) fmt.Printf("Phone: %q\n", v.Phone) fmt.Printf("Email: %v\n", v.Email) fmt.Printf("Groups: %v\n", v.Groups) fmt.Printf("Address: %v\n", v.Address)

下面是unmarshal解析的解析規則(下面的規則是從golang的官方文件中翻譯過來的):

1)如果該結構有一個型別為[]byte或string",innerxnl"的欄位。Unmarshal收集該欄位中元素內巢狀的原始xMI。其餘的規則仍然適用。

2)如果該結構有一個型別為xml . name的名為XMLName的欄位,Unnarshal記錄該欄位中的元素名。

3)如果XMLName欄位有表單的關聯標記"name" 或 “namespace-URL name”, 元素必須具有name(和 , 可選的 “name space”),否則Unnarshal返回錯誤。

4)如果XML元素具有一個屬性,該屬性的名字與struct結構體的欄位名字匹配(這個欄位的tag 包含",attr" 或者顯示包含name “name,attr”),Unmarshal記錄該欄位中的屬性值。

5)如果XML元素包含字元資料,該資料積累在第一個有標籤“chardata”的struct欄位中,該struct欄位的型別可能為[]byte或string。如果沒有這樣的欄位。字元資料被丟棄。

6)如果XML元素包含註釋,它們會累積在第一個帶有標籤",comments"的struct欄位中。struct欄位的型別可以是[]byte或string。如果沒有這樣的欄位,註釋將被丟棄。

7)如果XML元素包含名稱匹配的子元素標籤format tag的字首為“a”或“a>b>c”,unmarshal將進入XML結構查詢具有給定名稱的元素,並將最內層的元素對映到該struct欄位。以“>”開頭的標籤相當於一個以欄位名後跟“>”開頭的標籤。

8)如果XML元素包含一個子元素,該子元素的名稱與struct欄位的XMLName標籤匹配,並且struct欄位沒有按照前面的規則顯式的名稱標籤,unmarshal將該子元素對映到該struct欄位

9)如果XML元素包含一個子元素,它的名字匹配欄位中沒有任何模式標記(",attr", ", chardata"等)。Unmarshal 解析子元素到該結構欄位。

10)如果XML元素包含一個子元素,它不符合上面的任何規則,並且該結構有一個帶",any"標籤的欄位unmarshal 匹配子元素到該結構欄位”。

11)一個非指標匿名結構欄位被當作它的值的欄位是外部結構的一部分來處理。

12)帶有“-”標籤的struct欄位永遠不會被解編入。

2.將物件解析為xml,這個過程是上面過程的逆過程,不過很簡單,不用擔心

type Email struct {
		Where string `xml:"where,attr"`
		Addr  string
	}
	type Address struct {
		City, State string
	}
	type Result struct {
		// XMLName xml.Name `xml:"Person"`
		Name   string `xml:"FullName"`
		Phone  string
		Email  []Email
		Groups []string `xml:"Group>Value"`
		Address
	}
	type Root struct {
		XMLName xml.Name `xml:"root"`
		Res     Result   `xml:"Person"`
	}

	r := Root{
		Res: Result{
			Name:   "愛喝水的社長",
			Phone:  "18888888888",
			Email:  []Email{Email{Where: "c1", Addr: "[email protected]"}, Email{Where: "c2", Addr: "[email protected]"}},
			Groups: []string{"group1", "group2"},
			Address: Address{
				City:  "China",
				State: "aaa",
			},
		},
	}

	vbyte, err := xml.Marshal(r)
	if err != nil {
		fmt.Println("marshal err", err)
	}
	fmt.Printf("%v\n", string(vbyte))

上面程式碼的輸出結果為:

愛喝水的社長[email protected]@126.comgroup1group2Chinaaaa

與1中的xml結構相同!

以上就是go的xml的解析方式!

相同的內容在下面的公眾號中也同步更新,每天釋出一些程式設計知識,有興趣的朋友可以關注下,感謝大家支援!!
在這裡插入圖片描述