下面是與 12.9 節(jié) JSON 例子等價的 XML 版本:
<Person>
<FirstName>Laura</FirstName>
<LastName>Lynn</LastName>
</Person>
如同 json 包一樣,也有 Marshal()
和 UnMarshal()
從 XML 中編碼和解碼數(shù)據(jù);但這個更通用,可以從文件中讀取和寫入(或者任何實現(xiàn)了 io.Reader 和 io.Writer 接口的類型)
和 JSON 的方式一樣,XML 數(shù)據(jù)可以序列化為結(jié)構(gòu),或者從結(jié)構(gòu)反序列化為 XML 數(shù)據(jù);這些可以在例子 15.8(twitter_status.go)中看到。
encoding/xml 包實現(xiàn)了一個簡單的 XML 解析器(SAX),用來解析 XML 數(shù)據(jù)內(nèi)容。下面的例子說明如何使用解析器:
示例 12.17 xml.go:
// xml.go
package main
import (
"encoding/xml"
"fmt"
"strings"
)
var t, token xml.Token
var err error
func main() {
input := "<Person><FirstName>Laura</FirstName><LastName>Lynn</LastName></Person>"
inputReader := strings.NewReader(input)
p := xml.NewDecoder(inputReader)
for t, err = p.Token(); err == nil; t, err = p.Token() {
switch token := t.(type) {
case xml.StartElement:
name := token.Name.Local
fmt.Printf("Token name: %s\n", name)
for _, attr := range token.Attr {
attrName := attr.Name.Local
attrValue := attr.Value
fmt.Printf("An attribute is: %s %s\n", attrName, attrValue)
// ...
}
case xml.EndElement:
fmt.Println("End of token")
case xml.CharData:
content := string([]byte(token))
fmt.Printf("This is the content: %v\n", content)
// ...
default:
// ...
}
}
}
輸出:
Token name: Person
Token name: FirstName
This is the content: Laura
End of token
Token name: LastName
This is the content: Lynn
End of token
End of token
包中定義了若干 XML 標(biāo)簽類型:StartElement,Chardata(這是從開始標(biāo)簽到結(jié)束標(biāo)簽之間的實際文本),EndElement,Comment,Directive 或 ProcInst。
包中同樣定義了一個結(jié)構(gòu)解析器:NewParser
方法持有一個 io.Reader(這里具體類型是 strings.NewReader)并生成一個解析器類型的對象。還有一個 Token()
方法返回輸入流里的下一個 XML token。在輸入流的結(jié)尾處,會返回(nil,io.EOF)
XML 文本被循環(huán)處理直到 Token()
返回一個錯誤,因為已經(jīng)到達文件尾部,再沒有內(nèi)容可供處理了。通過一個 type-switch 可以根據(jù)一些 XML 標(biāo)簽進一步處理。Chardata 中的內(nèi)容只是一個 []byte,通過字符串轉(zhuǎn)換讓其變得可讀性強一些。