Go 語言 XML處理

2021-09-12 20:43:17 字數 3134 閱讀 8545

xml 應用於 web 開發的許多方面,常用於簡化資料的儲存和共享。

什麼是 xml?

看如下的 xml 示例:

<?xml version="1.0" encoding="utf-8"?>

shanghai_vpn

127.0.0.1

beijing_vpn

127.0.0.2

解析 xml 用到了 go 的encoding/xml包,可用該包的unmarshal函式來達到目的:

func unmarshal(data byte, v inte***ce{}) error
data 接收的是 xml 資料流,v 是需要輸出的結構,定義為 inte***ce,也就是可以把 xml 轉換為任意的格式。這裡主要介紹 struct 的轉換,因為 struct 和 xml 都有類似樹結構的特徵。

示例**如下:

type recurlyservers struct 

type server struct

func main()

defer file.close()

data, err := ioutil.readall(file)

if err != nil

v := recurlyservers{}

err = xml.unmarshal(data, &v)

if err != nil

fmt.println(v)

}

xml 本質上是一種樹形的資料格式,可以定義與之匹配的 go 語言的 struct 型別,然後通過xml.unmarshal 來將 xml 中的資料解析成對應的 struct 物件。如上例子輸出如下資料:

1 [ shanghai_vpn 127.0.0.1}  beijing_vpn 127.0.0.2}]

shanghai_vpn

127.0.0.1

beijing_vpn

127.0.0.2

}

上面的例子中,將 xml 檔案解析成對應的 struct 物件是通過 xml.unmarshal 來完成的。可以看到 struct 定義後面多了一些類似於 xml:「servername」 這樣的內容,這個是 struct 的乙個特性,它們被稱為 struct tag,它們是用來輔助反射的。來看一下unmarshal的定義:

func unmarshal(data byte, v inte***ce{}) error
可以看到函式定義了兩個引數,第乙個是 xml 資料流,第二個是儲存的對應型別,目前支援struct、slice和string,xml 包內部採用了反射來進行資料的對映,所以 v 裡面的字段必須是匯出的。unmarshal 解析的時候 xml 元素和字段的對應是有乙個優先順序讀取流程的,首先會讀取 struct tag,如果沒有,那麼就會對應欄位名。必須注意一點的是解析的時候 tag、欄位名、xml 元素都是大小寫敏感的,所以必須一一對應字段。

go 語言的反射機制,可以利用這些 tag 資訊來將來自 xml 檔案中的資料反射成對應的 struct物件。

解析 xml 到 struct 的時候遵循如下的規則:

shanghai_vpn

127.0.0.1

beijing_vpn

127.0.0.2

上面詳細講述了如何定義 struct 的 tag。 只要設定對了tag,那麼xml解析就如上面示例般簡單,tag和xml的element是一一對應的關係,如上所示,還可以通過slice來表示多個同級元素。

注意: 為了正確解析,go語言的xml包要求struct定義中的所有字段必須是可匯出的(即首字母大寫)

生成所示的 xml 檔案,xml 包中提供了 marshal 和 marshalindent 兩個函式,來滿足需求。這兩個函式主要的區別是第二個函式會增加字首和縮排,函式的定義如下所示:

func marshal(v inte***ce{}) (byte, error)

func marshalindent(v inte***ce{}, prefix, indent string) (byte, error)

兩個函式第乙個引數是用來生成xml的結構定義型別資料,都是返回生成的xml資料流。

下面來看一下如何輸出如上的xml:

type servers struct 

type server struct

func main()

output, err := xml.marshalindent(v, " ", " ")

if err != nil

os.stdout.write(byte(xml.header))

os.stdout.write(output)

}

輸出為:

<?xml version="1.0" encoding="utf-8"?>

shanghai_vpn

127.0.0.1

beijing_vpn

127.0.0.2

和之前定義的檔案的格式一樣,之所以會有 os.stdout.write(byte(xml.header)) 這句**的出現,是因為 xml.marshalindent 或者 xml.marshal 輸出的資訊都是不帶xml頭的,為了生成正確的xml檔案,在這裡使用了xml包預定義的header變數。

可以看到marshal函式接收的引數v是inte***ce{}型別的,即它可以接受任意型別的引數,那麼xml包,根據什麼規則來生成相應的xml檔案呢?

生成的xml檔案中的element的名字又是根據什麼決定的呢?元素名按照如下優先順序從struct中獲取:

我們應如何設定struct 中字段的tag資訊以控制最終xml檔案的生成呢?

firstname string   `xml:"name>first"`

lastname string `xml:"name>last"`

asta

xie

使用go語言解析xml

作業系統 centos 6.9 x64 go語言版本 1.8.3 現有乙個自動報障程式,如果服務出錯會自動給指定人傳送郵件,配置檔案內容如下 default.xml xml version 1.0 encoding utf 8 config smtpserver smtp.163.com smtps...

GO 語言 錯誤處理

1 go錯誤處理機制,沒有try,catch 處理方式是 defer,panic,recover go丟擲乙個panic的異常,然後在defer中通過recover捕獲這個異常func test a 1 b 0 c a b c 1 0 捕獲不到 fmt.println c error main.go...

go語言基礎異常處理

異常處理模板 package main import fmt 異常處理 defer panic recover defer 表示延遲呼叫,即便程式出現嚴重錯誤,也會執行 panic 就是python中的raise 主動丟擲異常 recover 恢復程式,繼續執行 func main func f1 ...