XML 處理,Go 標準庫太簡單了怎麼辦?
閱讀本文大概需要 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
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Neuc_hiVsVE83d47e40l6w