Go入門很簡單:解析 XML文件的 Unmarshal 函數

      網友投稿 960 2025-04-01

      解析 XML 文件的 Unmarshal 函數

      解析 XML 到 struct 的規則

      總結

      解析 XML 文件的 Unmarshal 函數

      解析 XML 到 struct 的規則

      總結

      解析 XML 文件的 Unmarshal 函數

      我們來看一下 Unmarshal 的定義:

      func Unmarshal(data []byte, v interface{}) error

      我們看到函式定義了兩個參數,第一個是 XML 文件流,第二個是儲存的對應類型,目前支持:

      結構體 struct

      切片 slice

      Go入門很簡單:解析 XML文件的 Unmarshal 函數

      字符串 string

      Go 有一個使用 NewParser()創建的 XML 解析器。 這需要一個 io.Reader() 作為參數并返回一個指向 Parser 的指針。 如果 XML 文件在用戶標簽、嵌套元素上設置了屬性,如果您能夠解析這些屬性,那么通過擴展,您應該能夠解析任何大小的 XML 文件。

      現在新建一個用來測試的 test.xml 文件:

      Guangzhou_node1 127.0.0.1 Guangzhou_node2 127.0.0.2

      如何解析如上這個 XML 文檔呢?我們可以透過 xml 模塊的 Unmarshal() 函數來達到我們的目的:

      func Unmarshal(data []byte, v interface{}) error

      data 接收的是 XML 文件流,v 是需要輸出的結構,定義為 interface,也就是可以把 XML 轉換為任意的格式。我們這里主要介紹 struct 的轉換,因為 struct 和 XML 都有類似樹狀結構的特征。

      定義我們的結構體:

      type Recurlyservers struct { XMLName xml.Name `xml:"servers"` Version string `xml:"version,attr"` Svs []server `xml:"server"` Description string `xml:",innerxml"` } type server struct { XMLName xml.Name `xml:"server"` ServerName string `xml:"serverName"` ServerIP string `xml:"serverIP"` }

      完整代碼:

      package main import ( "encoding/xml" "fmt" "io/ioutil" "os" ) type Recurlyservers struct { XMLName xml.Name `xml:"servers"` Version string `xml:"version,attr"` Svs []server `xml:"server"` Description string `xml:",innerxml"` } type server struct { XMLName xml.Name `xml:"server"` ServerName string `xml:"serverName"` ServerIP string `xml:"serverIP"` } func main() { file, err := os.Open("test.xml") // For read access. if err != nil { fmt.Printf("error: %v", err) return } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { fmt.Printf("error: %v", err) return } v := Recurlyservers{} err = xml.Unmarshal(data, &v) if err != nil { fmt.Printf("error: %v", err) return } fmt.Println(v) }

      XML 本質上是一種樹狀結構,而我們可以定義與之匹配的 go 語言的結構體類型,然后通過xml.Unmarshal 來將 xml 中的文件解析成對應的 struct 結構體。如上例子輸出如下結果:

      {{ servers} 1 [{{ server} Guangzhou_node1 127.0.0.1} {{ server} Guangzhou_node2 127.0.0.2}] Guangzhou_node1 127.0.0.1 Guangzhou_node2 127.0.0.2 }

      上面的例子中,將 xml 文件解析成對應的 struct 結構體是通過 xml.Unmarshal 來完成的,

      這個過程是如何實現的?可以看到我們的 struct 定義后面多了一些類似于 xml:"serverName" 這樣的內容,這個是 struct 的一個特性,它們被稱為 struct tag,它們是用來輔助反射的。

      XML 套件內部采用了反射來進行文件的對映,所以 v 里面的位置必須是輸出的。Unmarshal 解析的時候 XML 元素和對應類型怎么對應起來的呢?

      利用一個先后順序讀取:首先會讀取 struct tag,如果沒有,那么就會對應欄位名。必須注意一點的是解析的時候 tag、欄位名、XML 元素都是區分大小寫的的,所以必須一一對應。

      解析 XML 到 struct 的規則

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

      如果 struct 的第二個參數是 string 或者 []byte 型,并且它的 tag 含有 ",innerxml",Unmarshal 將會將此位置所對應的元素內所有內嵌的原始 xml 累加到此位置的元素,其余規則仍然適用。

      如上面例子 Description 定義。最后的輸出是:

      Shanghai_VPN 127.0.0.1 Beijing_VPN 127.0.0.2

      如果 struct 有一個名為 XMLName 的字段名稱,Unmarshal 在該字段中記錄元素名稱。

      如果 XMLName 字段具有表單的關聯標記 "name" 或"namespace-URL name",XML元素必須具有

      給定的名稱(以及可選的名稱空間)或 Unmarshal 返回錯誤。

      如果 XML 元素具有名稱與 a 匹配的屬性 struct field name,其關聯標記包含 ",attr" 或

      "name,attr" 形式的struct field標簽中的顯式名稱,Unmarshal 在該字段中記錄屬性值。

      如果 XML 元素的屬性未由前一個處理規則和 struct 有一個字段,其中包含相關的標記",any,attr",Unmarshal在第一個中記錄屬性值這樣的領域。

      如果 XML 元素包含字符數據,那么該數據就是累積在第一個具有標記 ",chardata" 的 struct 字段中。struct字段可以有 type [] byte 或 string。如果沒有這樣的字段,則丟棄字符數據。

      如果 XML 元素包含注釋,則會累積它們第一個帶有標記 ",comment" 的 struct 字段。結構字段可以有 type [] byte 或 string 。如果沒有這樣的話字段,comment 會被丟棄。

      如果 XML 元素包含名稱匹配的子元素格式化為 "a"或 "a> b> c"的標記的前綴,unmarshal 將下降到XML 結構中尋找帶有的元素給定名稱,并將最內層元素映射到該結構領域。以 ">" 開頭的標簽相當于一個開始字段名稱后跟 ">"。

      如果 XML 元素包含名稱匹配的子元素 struct 字段的 XMLName 標記,struct字段沒有根據先前規則的顯式名稱標簽,unmarshal 映射該 struct 字段的子元素。

      如果 XML 元素包含名稱與 a 匹配的子元素沒有任何模式標志的字段(",attr",",chardata" 等),Unmarshal 將子元素映射到該struct字段。

      如果 XML 元素包含未匹配任何子元素以上規則和 struct 有一個標記為 ",any" 的字段,unmarshal 將子元素映射到該struct字段。

      處理匿名結構字段,就像它的字段一樣 value 是外部結構的一部分。

      帶有標記" - " 的結構字段永遠不會被 unmarshal。

      總結

      本文作為學習筆記,主要介紹了如何解析 XML 文件的 Unmarshal() 函數。之后再去探索更多的用法,比如在?Web?開發中讀取配置文件,或者接收?XML?文件格式的文件,或者看到 XML 格式和 JSON 格式做轉換。

      推薦閱讀:

      Go by Example: XML

      Parse and generate XML easily in golang

      Go XML

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何在Google工作表中用換行符連接多個單元格?
      下一篇:如何在Google表格的單元格中反轉名字和姓氏?
      相關文章
      亚洲欧洲精品成人久久奇米网| 亚洲中文字幕日本无线码| 亚洲日韩精品无码AV海量| 亚洲AV人无码综合在线观看| 亚洲日韩人妻第一页| 国产偷国产偷亚洲清高动态图 | 亚洲第一综合天堂另类专| 亚洲娇小性色xxxx| 国产精品亚洲精品观看不卡| 亚洲一级片在线播放| 亚洲国产美女精品久久久久| 亚洲第一香蕉视频| 亚洲制服丝袜一区二区三区| 久久精品国产亚洲AV忘忧草18 | 亚洲精品国产成人影院| 亚洲国产精品综合久久一线| 亚洲成AⅤ人影院在线观看| 亚洲第一成人影院| 国产精品亚洲产品一区二区三区 | 亚洲不卡在线观看| 男人天堂2018亚洲男人天堂| 亚洲一久久久久久久久| 亚洲爆乳大丰满无码专区| 亚洲色大成网站www久久九| 亚洲国产精品嫩草影院| 最新亚洲人成无码网www电影| 爱情岛亚洲论坛在线观看 | 日韩国产欧美亚洲v片| 大桥未久亚洲无av码在线| 亚洲精品tv久久久久久久久久| 亚洲爆乳大丰满无码专区| 亚洲国产精品狼友中文久久久| 亚洲国产小视频精品久久久三级| 亚洲伊人久久综合中文成人网| 亚洲自偷自偷在线制服| 亚洲综合精品一二三区在线| 蜜芽亚洲av无码精品色午夜| 亚洲噜噜噜噜噜影院在线播放| 亚洲最大福利视频| 国产青草亚洲香蕉精品久久| 中文字幕亚洲激情|