diff --git a/eBook/12.10.md b/eBook/12.10.md new file mode 100644 index 0000000..e95750a --- /dev/null +++ b/eBook/12.10.md @@ -0,0 +1,81 @@ +# XML数据格式 +下面是与12.9节json例子等价的XML版本: +```xml + + Laura + Lynn + +``` + +如同json包中`Marshal()`和`UnMarshal()`函数一样,从XML中编码和解码数据;但这个更通用,可以从文件中读取和写入(或者任何实现了io.Reader和io.Writer接口的类型) + +和json的方式一样,xml数据可以序列化为结构,或者从结构反序列化为xml数据;这些可以在例子15.8(twitter_status.go)中看到。 + +encoding/xml包实现了一个简单的xml解析器(SAX),用来解析XML数据内容。下面的例子说明如何使用解析器: + +示例 12.17 [xml.go](examples/chapter_12/xml.go): + +```go +// xml.go +package main + +import ( + "encoding/xml" + "fmt" + "strings" +) + +var t, token xml.Token +var err error + +func main() { + input := "LauraLynn" + 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: + // ... + } + } +} + +/* Output: +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标签类型:StartElement,Chardata(这是从开始标签到结束标签之间的实际文本),EndElement,Comment,Directive 或 ProcInst. + +包中同样定义了一个结构解析器:`NewParser`方法持有一个io.Reader(这里具体类型是strings.NewReader)并生成一个解析器类型的对象。还有一个`Token()`方法返回输入流里的下一个XML token。在输入流的结尾处,会返回(nil, io.EOF) + +XML文本被循环处理直到`Token()`返回一个错误,因为已经到达文件尾部,再没有内容可供处理了。通过一个type-switch可以根据一些XML标签进一步处理。Chardata中的内容只是一个[]byte,通过字符串转换让其变得可读性强一些。 + +## 链接 + +- [目录](directory.md) +- 上一节:[Json数据格式](12.9.md) +- 下一节:[XML数据格式](12.11.md)