Golang基础(xml文件)

it2024-03-27  55

一.XML文件简介

英文全称:Extensible Markup Language

中文全称:可扩展标记语言

用途:

数据存储

数据交互

配置文件

优点:

跨平台性

数据工整,易读

二.XML文档结构

XML文档结构

第一行:XML头,版本和编码

第二行:DTD可选,能够检查XML内容是否满足要求

最外层标签<peoples> 称为元素节点,根节点

<people>...<people> 整个标签称为元素节点

id=”1” 属性节点e

标签中文字:文本节点

示例如下

三.语法要求

严格区分大小写

标签必须正确嵌套,必须正确关闭

必须有根节点

属性值必须有双引号

注释:<!-- -->

文本节点出现特殊字符,需要使用实体引用替换

 

四、Go语言标准库提供的API

在encoding/xml包下提供了对XML序列化和反序列化的API

使用Unmarshal可以直接把XML字节切片数据转换为结构体

转换时按照特定的转换规则进行转换,且数据类型可以自动转换

* 如果结构体字段的类型为字符串或者[]byte,且标签为",innerxml", Unmarshal函数直接将对应原始XML文本写入该字段,其余规则仍适用。 * 如果结构体字段类型为xml.Name且名为XMLName,Unmarshal会将元素名写入该字段 * 如果字段XMLName的标签的格式为"name"或"namespace-URL name", XML元素必须有给定的名字(以及可选的名字空间),否则Unmarshal会返回错误。 * 如果XML元素的属性的名字匹配某个标签",attr"为字段的字段名,或者匹配某个标签为"name,attr" 的字段的标签名,Unmarshal会将该属性的值写入该字段。 * 如果XML元素包含字符数据,该数据会存入结构体中第一个具有标签",chardata"的字段中, 该字段可以是字符串类型或者[]byte类型。如果没有这样的字段,字符数据会丢弃。 * 如果XML元素包含注释,该数据会存入结构体中第一个具有标签",comment"的字段中, 该字段可以是字符串类型或者[]byte类型。如果没有这样的字段,字符数据会丢弃。 * 如果XML元素包含一个子元素,其名称匹配格式为"a"或"a>b>c"的标签的前缀,反序列化会深入 XML结构中寻找具有指定名称的元素,并将最后端的元素映射到该标签所在的结构体字段。 以">"开始的标签等价于以字段名开始并紧跟着">" 的标签。 * 如果XML元素包含一个子元素,其名称匹配某个结构体类型字段的XMLName字段的标签名, 且该结构体字段本身没有显式指定标签名,Unmarshal会将该元素映射到该字段。 * 如果XML元素的包含一个子元素,其名称匹配够格结构体字段的字段名,且该字段没有任何模式选项 (",attr"、",chardata"等),Unmarshal会将该元素映射到该字段。 * 如果XML元素包含的某个子元素不匹配以上任一条,而存在某个字段其标签为",any", Unmarshal会将该元素映射到该字段。 * 匿名字段被处理为其字段好像位于外层结构体中一样。 * 标签为"-"的结构体字段永不会被反序列化填写。

 XML文件读取

给定XML文件内容如下

<?xml version="1.0" encoding="UTF-8" ?> <people id="888">    <name>smallming</name>    <address>北京海淀</address> </people>

新建结构体,装载XML数据

结构体中属性首字母必须大写,否则无法装配

type People struct { XMLName xml.Name `xml:"people"` Id      int      `xml:"id,attr"` Name    string   `xml:"name"` Address string   `xml:"address"` } ​ func main() { peo := new(People) b, err := ioutil.ReadFile("demo.xml") fmt.Println(string(b)) fmt.Println("111:", err) err = xml.Unmarshal(b, peo) fmt.Println("2222", err) fmt.Println(peo) }

三.多层嵌套XML文件读取

给定XML中数据如下

<?xml version="1.0" encoding="UTF-8" ?> <peoples version="0.9">    <people id="888">        <name>smallming</name>        <address>北京海淀</address>    </people>    <people id="998">        <name>佳明哥</name>        <address>北京朝阳</address>    </people> </peoples> ​

编写读取XML数据代码

type Peoples struct { XMLName xml.Name `xml:"peoples"` Version string   `xml:"version,attr"` Peos   []People `xml:"people"` } ​ type People struct { XMLName xml.Name `xml:"people"` Id      int      `xml:"id,attr"` Name    string   `xml:"name"` Address string   `xml:"address"` } ​ func main() { peo := new(Peoples) b, err := ioutil.ReadFile("demo.xml") fmt.Println(string(b)) fmt.Println("111:", err) err = xml.Unmarshal(b, peo) fmt.Println("2222", err) fmt.Println(peo) }

生成XML

生成XML只要在学习下encoding/xml包下的Marshal()函数,结合输入流就可以完成xml文件生成

在encoding/xml中有常量,常量中是xml文档头

const ( // Header is a generic XML header suitable for use with the output of Marshal. // This is not automatically added to any output of this package, // it is provided as a convenience. Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n" )

代码示例

使用Marshal()函数生成的[]byte没有格式化

使用MarshalIndent()可以对内容进行格式化

第一个参数:结构体对象

第二个参数:每行的前缀

第三个参数:层级缩进内容

type People struct { XMLName xml.Name `xml:"people"` Id      int      `xml:"id,attr"` Name    string   `xml:"name"` Address string   `xml:"address"` } ​ func main() { peo := People{Id: 123, Name: "smallming", Address: "北京海淀"} b, _ := xml.MarshalIndent(peo, "", " ") b = append([]byte(xml.Header), b...) ioutil.WriteFile("D:/peo.xml", b, 0666) fmt.Println("程序结束") }

 

最新回复(0)