<commit_before># 7.1 XML处理
XML作为一种数据交换和信息传递的格式已经十分普及。而随着Web服务日益广泛的应用，现在XML在日常的开发工作中也扮演了愈发重要的角色。这一小节， 我们将就Go语言标准包中的XML相关处理的包进行介绍。

这个小节不会涉及XML规范相关的内容（如需了解相关知识请参考其他文献），而是介绍如何用Go语言来编解码XML文件相关的知识。

假如你是一名运维人员，你为你所管理的所有服务器生成了如下内容的xml的配置文件：

	<?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文档描述了两个服务器的信息，包含了服务器名和服务器的IP信息，接下来的Go例子以此XML描述的信息进行操作。

## 解析XML
如何解析如上这个XML文件喃呢？ 我们可以通过xml包的`Unmarshal`函数来达到我们的目的

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

data接收的是XML数据流，v是需要输出的结构，定义为interface，也就是可以把XML转换为任意的格式。我们这里主要介绍struct的转换，因为struct和XML都有类似树结构的特征。

示例代码如下：

	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("servers.xml") // For read access.
		defer file.Close()
		if err != nil {
			fmt.Printf("error: %v", err)
			return
		}
		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
		}
<commit_msg>修复代码的bug<commit_after># 7.1 XML处理
XML作为一种数据交换和信息传递的格式已经十分普及。而随着Web服务日益广泛的应用，现在XML在日常的开发工作中也扮演了愈发重要的角色。这一小节， 我们将就Go语言标准包中的XML相关处理的包进行介绍。

这个小节不会涉及XML规范相关的内容（如需了解相关知识请参考其他文献），而是介绍如何用Go语言来编解码XML文件相关的知识。

假如你是一名运维人员，你为你所管理的所有服务器生成了如下内容的xml的配置文件：

	<?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文档描述了两个服务器的信息，包含了服务器名和服务器的IP信息，接下来的Go例子以此XML描述的信息进行操作。

## 解析XML
如何解析如上这个XML文件喃呢？ 我们可以通过xml包的`Unmarshal`函数来达到我们的目的

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

data接收的是XML数据流，v是需要输出的结构，定义为interface，也就是可以把XML转换为任意的格式。我们这里主要介绍struct的转换，因为struct和XML都有类似树结构的特征。

示例代码如下：

	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("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
		}

{'fraction_non_alphanumeric': 0.13895001571832757, 'fraction_numerical': 0.011317195850361521, 'mean_word_length': 4.365935919055649, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 2, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 32}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7256432', 'n_tokens_mistral': 1772, 'n_tokens_neox': 1760, 'n_words': 212}