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 ...