完成12.10章节

This commit is contained in:
kuuyee
2015-10-15 00:15:55 +08:00
parent c02f5be516
commit b12c9f15c6

81
eBook/12.10.md Normal file
View File

@@ -0,0 +1,81 @@
# XML数据格式
下面是与12.9节json例子等价的XML版本
```xml
<Person>
<FirstName>Laura</FirstName>
<LastName>Lynn</LastName>
</Person>
```
如同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 := "<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:
// ...
}
}
}
/* 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(这是从开始标签到结束标签之间的实际文本)EndElementCommentDirective 或 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)