前言
XML是指可擴展標記語言(eXtensible MarkupLanguage),它是一種標記語言。它被設計的宗旨是描述數據(XML),而非顯示數據(HTML)。
在日常開發中是比較流行的傳輸和存儲數據結構。
Go語言中,我們用xml包的Unmarshal來解析XML文檔,MarshalIndent來生成XML文檔。
XML文檔實例
<?xml version="1.0" encoding="utf-8"?>
<devices version="1">
<device>
<deviceName>智能攝像頭</deviceName>
<deviceCode>100000000001</deviceCode>
<deviceDate>2020-03-01</deviceDate>
</device>
<device>
<deviceName>智能挖掘機</deviceName>
<deviceCode>200000000001</deviceCode>
<deviceDate>2020-03-01</deviceDate>
</device>
</devices>
定義結構
type Device struct {
XMLName xml.Name `xml:"devices"`
Version string `xml:"version,attr"`
Device []DeviceNode `xml:"device"`
Description string `xml:",innerxml"`
}
type DeviceNode struct {
XMLName xml.Name `xml:"device"`
DeviceName string `xml:"deviceName"`
DeviceCode string `xml:"deviceCode"`
DeviceDate string `xml:"deviceDate"`
}
Tag解釋
- "-",字段不會輸出
- "name,attr",以name作爲屬性名,字段值作爲輸出這個XML元素的屬性
- ",attr",以這個結構體struct的字段名作爲屬性名輸出XML元素的屬性,name默認是字段名
- ",chardata",輸出XML元素爲character data而非element。
- ",innerxml",原樣輸出,不進行常規的編碼過程
- ",comment",作爲XML註釋來輸出,不進行編碼過程,字段中不能有“--”字符串
- "omitempty",若字段值爲空、那麼字段不會被輸出到XML,空值有:false、0、nil指針,nil接口,任意長度爲0的Slice、數組結構、Map結構或者string
生成XML
var o = Device{}
o.Device = append(o.Device, DeviceNode{
DeviceName: "電腦",
DeviceCode: "300000000001",
DeviceDate: "2020-01-01",
})
o.Device = append(o.Device, DeviceNode{
DeviceName: "遊戲機",
DeviceCode: "400000000001",
DeviceDate: "2020-01-02",
})
o.Device = append(o.Device, DeviceNode{
DeviceName: "蘋果手機",
DeviceCode: "500000000001",
DeviceDate: "2020-01-03",
})
resXML, err := xml.MarshalIndent(o, " ", " ")
if err != nil {
fmt.Printf("marshal xml err :%v\n", err)
return
}
_, _ = os.Stdout.Write([]byte(xml.Header))
_, _ = os.Stdout.Write(resXML)
解析XML
file := "./device.xml"
fd, err := os.Open(file)
if err != nil {
fmt.Printf("open file err : %v\n", err)
return
}
defer fd.Close()
fileContent, err := ioutil.ReadAll(fd)
if err != nil {
fmt.Printf("read file err : %v\n", err)
return
}
var device = Device{}
err = xml.Unmarshal(fileContent, &device)
if err != nil {
fmt.Printf("unmarshal err : %v\n", err)
return
}
for idx, node := range device.Device {
fmt.Printf("序號:[%d],設備名:[%s],設備編碼:[%s],設備日期:[%s]\n",
idx, node.DeviceName, node.DeviceCode, node.DeviceDate)
}
運行結果