Go每日一库之 XML 处理
2023-5-29 08:54:55 Author: Go语言中文网(查看原文) 阅读量:20 收藏

阅读本文大概需要 4 分钟。

虽然官方有 xml 处理的库,但比较简单。今天介绍一个基于官方 xml 库的增强库:etree https://github.com/beevik/etree,它是一个轻量级的纯 Go 包,它可以用于以元素树的形式表示 XML 文档。它的设计受到了 Python ElementTree 模块的启发。

etree 的特点

  • 支持导入、序列化、修改或从头创建 XML 文档
  • 支持将 XML 写入和读取文件、字节切片、字符串和 io 接口
  • 支持使用超时时间来保留任务,如果超时或失败,会重新入队
  • 支持使用空格或制表符来自动缩进 XML,提高可读性
  • 依赖于标准的 Go 库,不需要安装其他第三方库
  • 基于 Go 的 encoding/xml 包构建

etree 的使用方法

  • 可以用 etree.NewDocument 函数来创建一个新的 XML 文档,或者用 etree.Read* 系列函数来从不同的源读取 XML 文档,例如:
doc := etree.NewDocument()
if err := doc.ReadFromFile("bookstore.xml"); err != nil {
  panic(err)
}
  • 可以用 etree.Element 结构体来表示 XML 文档中的元素,它有一些方法来创建、获取或修改元素的属性、子元素、文本内容等,例如:
root := doc.SelectElement("bookstore")
book := root.CreateElement("book")
book.CreateAttr("category""WEB")
title := book.CreateElement("title")
title.SetText("Go in Action")
  • 可以用 etree.Path 函数来根据类似 XPath 的路径表达式来查找元素,例如:
books := root.SelectElements("book")
for _, book := range books {
  title := book.SelectElement("title")
  fmt.Println(title.Text())
}
  • 可以用 etree.Write* 系列函数来将 XML 文档写入不同的目标,例如:
doc.Indent(2)
doc.WriteTo(os.Stdout)

etree 库的具体案例

假设你有一个 XML 文件,叫做 students.xml,它的内容是这样的:

<students>
  <student id="1">
    <name>Tom</name>
    <age>18</age>
    <score>90</score>
  </student>
  <student id="2">
    <name>Alice</name>
    <age>19</age>
    <score>95</score>
  </student>
  <student id="3">
    <name>Bob</name>
    <age>20</age>
    <score>85</score>
  </student>
</students>

你想用 etree 来读取这个文件,并对其中的元素进行一些操作,例如:

  • 打印出所有学生的姓名和分数
  • 修改第二个学生的分数为 100
  • 删除第三个学生的元素
  • 添加一个新的学生元素
  • 将修改后的 XML 文档保存到一个新的文件中

你可以用以下的 Go 代码来实现这些操作:

package main

import (
 "fmt"
 "github.com/beevik/etree"
)

func main() {
 // 创建一个新的 XML 文档对象
 doc := etree.NewDocument()
 // 从文件中读取 XML 文档内容
 if err := doc.ReadFromFile("students.xml"); err != nil {
  panic(err)
 }
 // 获取根元素 students
 root := doc.SelectElement("students")
 // 遍历根元素的所有子元素 student
 for _, student := range root.SelectElements("student") {
  // 获取 student 元素的 id 属性值
  id := student.SelectAttrValue("id""unknown")
  // 获取 student 元素的 name 子元素的文本内容
  name := student.SelectElement("name").Text()
  // 获取 student 元素的 score 子元素的文本内容
  score := student.SelectElement("score").Text()
  // 打印出 id, name 和 score
  fmt.Printf("Student %s: %s, %s\n", id, name, score)
 }
 // 修改第二个 student 元素的 score 子元素的文本内容为 100
 root.SelectElement("student[2]").SelectElement("score").SetText("100")
 // 删除第三个 student 元素
 root.RemoveChild(root.SelectElement("student[3]"))
 // 添加一个新的 student 元素
 newStudent := root.CreateElement("student")
 newStudent.CreateAttr("id""4")
 newStudent.CreateElement("name").SetText("Cathy")
 newStudent.CreateElement("age").SetText("21")
 newStudent.CreateElement("score").SetText("88")
 // 将修改后的 XML 文档保存到一个新的文件中
 doc.Indent(2)
 doc.WriteToFile("new_students.xml")
}

运行这段代码后,你会看到以下的输出:

Student 1: Tom, 90
Student 2: Alice, 95
Student 3: Bob, 85

并且,你会在当前目录下生成一个新的文件 new_students.xml,它的内容是这样的:

<students>
  <student id="1">
    <name>Tom</name>
    <age>18</age>
    <score>90</score>
  </student>
  <student id="2">
    <name>Alice</name>
    <age>19</age>
    <score>100</score>
  </student>
  <student id="4">
    <name>Cathy</name>
    <age>21</age>
    <score>88</score>
  </student>
</students>

etree 的优缺点

etree 库的优点:

  • 它是一个轻量级的纯 Go 包,不需要安装其他第三方库,依赖于标准的 Go 库
  • 它可以用简单的结构体和方法来表示和操作 XML 文档中的元素和属性,易于使用和理解
  • 它可以用类似 XPath 的路径表达式来查找元素,支持一些常用的选择器和过滤器
  • 它可以用自动缩进的功能来提高 XML 文档的可读性,支持空格或制表符

etree 库的缺点:

  • 它不支持完整的 XPath 和 XSLT 功能,只能用简单的路径表达式来查找元素
  • 它不支持验证 XML 文档是否符合某种模式或规范,例如 DTD 或 XML Schema
  • 它不支持处理非 XML 格式的文档,例如 HTML 或 JSON
  • 它不支持处理 XML 文档中的 CDATA 节或注释

综上所述,etree 库是一个适合于 Go 开发者使用的轻量级和易用的 XML 处理库,它可以满足一些基本和常见的需求。


往期推荐

我是 polarisxu,北大硕士毕业,曾在 360 等知名互联网公司工作,10多年技术研发与架构经验!2012 年接触 Go 语言并创建了 Go 语言中文网!著有《Go语言编程之旅》、开源图书《Go语言标准库》等。

坚持输出技术(包括 Go、Rust 等技术)、职场心得和创业感悟!欢迎关注「polarisxu」一起成长!也欢迎加我微信好友交流:gopherstudio


文章来源: http://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651454395&idx=1&sn=69928c1e38fe52b0f52d072d90c0e844&chksm=80bb2549b7ccac5f118c2f783f9843b313993d189d333c58cd5a64b8b72c3f247913e162d84f#rd
如有侵权请联系:admin#unsafe.sh