<?xml version="1.0" encoding="utf-8"?>
<servers version="1">
 <server>
 <serverName>Shanghai_VPN</serverName>
 <serverIP>127.0.0.1</serverIP>
 </server>
 <server>
 <serverName>Beijing_VPN</serverName>
 <serverIP>127.0.0.2</serverIP>
 </server>
</servers>

解析 XML

func main() {
 file, err := os.Open("servers.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)
}
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"`
}
{{ servers} 1 [{{ server} Shanghai_VPN 127.0.0.1} {{ server} Beijing_VPN 127.0.0.2}] 
 <server>
 <serverName>Shanghai_VPN</serverName>
 <serverIP>127.0.0.1</serverIP>
 </server>
 <server>
 <serverName>Beijing_VPN</serverName>
 <serverIP>127.0.0.2</serverIP>
 </server>
}
structxml.Unmarshalstructslicestringv
func Unmarshal(data []byte, v interface{}) error
struct
func Marshal(v interface{}) ([]byte, error)
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

func main() {
 v := &Servers{Version: "1"}
 v.Svs = append(v.Svs, server{"Shanghai_VPN", "127.0.0.1"})
 v.Svs = append(v.Svs, server{"Beijing_VPN", "127.0.0.2"})
 output, err := xml.MarshalIndent(v, " ", " ")
 if err != nil {
 fmt.Printf("error: %v\n", err)
 }
 os.Stdout.Write([]byte(xml.Header))
 os.Stdout.Write(output)
}
xml:"servers"xml:"version,attr"xml:"server"
xml:"serverName"xml:"serverIP"

<?xml version="1.0" encoding="UTF-8"?>
<servers version="1">
<server>
<serverName>Shanghai_VPN</serverName>
<serverIP>127.0.0.1</serverIP>
</server>
<server>
<serverName>Beijing_VPN</serverName>
<serverIP>127.0.0.2</serverIP>
</server>
</servers>

`Marshal` 接收的参数 `v` 是 `interface{}` 类型的,即它可以接受任意类型的参数。
- 如果 `v` 是 `array` 或者 `slice`,那么输出每一个元素,类似 value。
- 如果 `v` 是指针,那么会输出指针指向的内容,如果指针为空,则什么都不输出。
- 如果 `v` 是 `interface`,那么就处理 `interface` 所包含的数据。
- 如果 `v` 是其他数据类型,就会输出这个数据类型所拥有的字段信息。
如何设置 `struct` 中字段的 tag 信息以控制最终 xml 文件的生成呢?(未指明部分可参考解析 xml 部分)
- tag 中含有 `",chardata"`,生成为 xml 的 character data,而非 element。
- tag 中含有 `",innerxml"`,将会被原样输出,而不会进行常规的编码过程。
- tag 中含有 `",comment"`,将会被当作 xml 注释来输出,而不会进行常规的编码过程,字段值中不能含有 `--` 字符串。
- tag 中含有 `"omitempty"`,如果该字段的值为空值那么该字段就不会被输出到 xml,空值包括:false、0、nil 指针或 nil 接口,任何长度为 0 的 array、slice、map 或 string。
- tag 中含有 `"a>b>c"`,那么就会循环输出三个元素 a 包含 b,b 包含 c,例如如下代码就会输出:
 ```go
 FirstName string `xml:"name>first"`
 LastName string `xml:"name>last"`
```
<name>
 <first>Asta</first>
 <last>Xie</last>
</name>
```