mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-08-15 02:51:34 +00:00
回到简体
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
## 7.14. 示例: 基於標記的XML解碼
|
||||
## 7.14. 示例: 基于标记的XML解码
|
||||
|
||||
第4.5章節展示了如何使用encoding/json包中的Marshal和Unmarshal函數來將JSON文檔轉換成Go語言的數據結構。encoding/xml包提供了一個相似的API。當我們想構造一個文檔樹的表示時使用encoding/xml包會很方便,但是對於很多程序併不是必須的。encoding/xml包也提供了一個更低層的基於標記的API用於XML解碼。在基於標記的樣式中,解析器消費輸入和産生一個標記流;四個主要的標記類型-StartElement,EndElement,CharData,和Comment-每一個都是encoding/xml包中的具體類型。每一個對(\*xml.Decoder).Token的調用都返迴一個標記。
|
||||
第4.5章节展示了如何使用encoding/json包中的Marshal和Unmarshal函数来将JSON文档转换成Go语言的数据结构。encoding/xml包提供了一个相似的API。当我们想构造一个文档树的表示时使用encoding/xml包会很方便,但是对于很多程序并不是必须的。encoding/xml包也提供了一个更低层的基于标记的API用于XML解码。在基于标记的样式中,解析器消费输入和产生一个标记流;四个主要的标记类型-StartElement,EndElement,CharData,和Comment-每一个都是encoding/xml包中的具体类型。每一个对(\*xml.Decoder).Token的调用都返回一个标记。
|
||||
|
||||
這里顯示的是和這個API相關的部分:
|
||||
这里显示的是和这个API相关的部分:
|
||||
|
||||
<u><i>encoding/xml</i></u>
|
||||
```go
|
||||
@@ -33,9 +33,9 @@ func NewDecoder(io.Reader) *Decoder
|
||||
func (*Decoder) Token() (Token, error) // returns next Token in sequence
|
||||
```
|
||||
|
||||
這個沒有方法的Token接口也是一個可識别聯合的例子。傳統的接口如io.Reader的目的是隱藏滿足它的具體類型的細節,這樣就可以創造出新的實現;在這個實現中每個具體類型都被統一地對待。相反,滿足可識别聯合的具體類型的集合被設計確定和暴露,而不是隱藏。可識别的聯合類型幾乎沒有方法;操作它們的函數使用一個類型開關的case集合來進行表述;這個case集合中每一個case中有不同的邏輯。
|
||||
这个没有方法的Token接口也是一个可识别联合的例子。传统的接口如io.Reader的目的是隐藏满足它的具体类型的细节,这样就可以创造出新的实现;在这个实现中每个具体类型都被统一地对待。相反,满足可识别联合的具体类型的集合被设计确定和暴露,而不是隐藏。可识别的联合类型几乎没有方法;操作它们的函数使用一个类型开关的case集合来进行表述;这个case集合中每一个case中有不同的逻辑。
|
||||
|
||||
下面的xmlselect程序獲取和打印在一個XML文檔樹中確定的元素下找到的文本。使用上面的API,它可以在輸入上一次完成它的工作而從來不要具體化這個文檔樹。
|
||||
下面的xmlselect程序获取和打印在一个XML文档树中确定的元素下找到的文本。使用上面的API,它可以在输入上一次完成它的工作而从来不要具体化这个文档树。
|
||||
|
||||
<u><i>gopl.io/ch7/xmlselect</i></u>
|
||||
```go
|
||||
@@ -89,9 +89,9 @@ func containsAll(x, y []string) bool {
|
||||
}
|
||||
```
|
||||
|
||||
每次main函數中的循環遇到一個StartElement時,它把這個元素的名稱壓到一個棧里;併且每次遇到EndElement時,它將名稱從這個棧中推出。這個API保證了StartElement和EndElement的序列可以被完全的匹配,甚至在一個糟糕的文檔格式中。註釋會被忽略。當xmlselect遇到一個CharData時,隻有當棧中有序地包含所有通過命令行參數傳入的元素名稱時它才會輸出相應的文本。
|
||||
每次main函数中的循环遇到一个StartElement时,它把这个元素的名称压到一个栈里;并且每次遇到EndElement时,它将名称从这个栈中推出。这个API保证了StartElement和EndElement的序列可以被完全的匹配,甚至在一个糟糕的文档格式中。注释会被忽略。当xmlselect遇到一个CharData时,只有当栈中有序地包含所有通过命令行参数传入的元素名称时它才会输出相应的文本。
|
||||
|
||||
下面的命令打印出任意出現在兩層div元素下的h2元素的文本。它的輸入是XML的説明文檔,併且它自己就是XML文檔格式的。
|
||||
下面的命令打印出任意出现在两层div元素下的h2元素的文本。它的输入是XML的说明文档,并且它自己就是XML文档格式的。
|
||||
|
||||
```
|
||||
$ go build gopl.io/ch1/fetch
|
||||
@@ -108,11 +108,11 @@ html body div div h2: B Definitions for Character Normalization
|
||||
...
|
||||
```
|
||||
|
||||
**練習 7.17:** 擴展xmlselect程序以便讓元素不僅僅可以通過名稱選擇,也可以通過它們CSS樣式上屬性進行選擇;例如一個像這樣<div id="page" class="wide">的元素可以通過匹配id或者class同時還有它的名稱來進行選擇。
|
||||
**练习 7.17:** 扩展xmlselect程序以便让元素不仅仅可以通过名称选择,也可以通过它们CSS样式上属性进行选择;例如一个像这样<div id="page" class="wide">的元素可以通过匹配id或者class同时还有它的名称来进行选择。
|
||||
|
||||
**練習 7.18:** 使用基於標記的解碼API,編寫一個可以讀取任意XML文檔和構造這個文檔所代表的普通節點樹的程序。節點有兩種類型:CharData節點表示文本字符串,和 Element節點表示被命名的元素和它們的屬性。每一個元素節點有一個字節點的切片。
|
||||
**练习 7.18:** 使用基于标记的解码API,编写一个可以读取任意XML文档和构造这个文档所代表的普通节点树的程序。节点有两种类型:CharData节点表示文本字符串,和 Element节点表示被命名的元素和它们的属性。每一个元素节点有一个字节点的切片。
|
||||
|
||||
你可能發現下面的定義會對你有幫助。
|
||||
你可能发现下面的定义会对你有帮助。
|
||||
|
||||
```go
|
||||
import "encoding/xml"
|
||||
|
Reference in New Issue
Block a user