Web 开发中需要对输入、输出进行处理。
XML 处理
示例 XML 文件如下:
1 |
|
读取 XML
读取 XML 选择 xml.Unmarshal 函数:
1 | func Unmarshal(data []byte, v interface{}) error |
将 XML 写入结构体为例,上述 XML 文件 对应的结构体为:
1 | type Servers struct { |
读取操作:
1 | func main() { |
输出 XML
xml 包提供了两个函数 Marshal 和 MarshalIndent 来输出 XML,二者的区别在于 MarshalIndent 会增加前缀和缩进:
1 | func Marshal(v interface{}) ([]byte, error) |
构建结构体:
1 | type Servers struct { |
解析结构体并输出 XML :
1 | func main() { |
注意:
之所以会有 os.Stdout.Write([]byte(xml.Header))
这句代码的出现,是因为 xml.MarshalIndent
或者 xml.Marshal
输出的信息都是不带 XML 头的,为了生成正确的 xml 文件,我们使用了 xml 包预定义的 Header 变量。
JSON 处理
示例 JSON 格式数据如下:
1 | { |
解析 JSON
json 包中有如下函数可以解析 JSON 数据:
1 | func Unmarshal(data []byte, v interface{}) error |
解析到结构体
上述 JSON 数据对应的结构体如下:
1 | type Server struct { |
解析 JSON 数据到结构体:
1 | func main() { |
解析到 interface
如果知道 JSON 数据的格式,可以解析到结构体中。如果不知道 JSON 数据格式,可以利用 map [string] interface {} 和 [] interface {} 结构来存储任意的 JSON 对象。
1 | var f interface{} |
此时,空接口 f 实际上是一个 map[string] interface{},其结构如下:
1 | map[string]interface {}{ |
可以通过类型断言将**空接口转为 map[string] interface{}**,接着就可以利用 for range 对 map 进行遍历了:
1 | m := f.(map[string]interface{}) |
目前,simplejson
包可以更加容易的处理未知结构的 JSON 数据,其 github 地址如下:
github.com/bitly/go-simplejson
生成 JSON
json 包提供了生成 JSON 数据的函数:
1 | func Marshal(v interface{}) ([]byte, error) |
这里不再举例说明具体操作。
模板处理
使用模板
解析模板
html/template 包中有两个函数可以解析模板:
- ParseFiles 函数创建一个模板并解析filenames指定的文件里的模板定义。返回的模板的名字是第一个文件的文件名(不含扩展名),内容为解析后的第一个文件的内容。
1 | func ParseFiles(filenames ...string) (*Template, error) |
- ParseGlob 函数创建一个模板并解析匹配 pattern 的文件里的模板定义。返回的模板的名字是第一个匹配的文件的文件名(不含扩展名),内容为解析后的第一个文件的内容。
1 | func ParseGlob(pattern string) (*Template, error) |
模板执行
html/template 包中有两个函数可以执行模板:
- Execute 方法将解析好的模板应用到 data 上,并将输出写入 wr。
1 | func (t *Template) Execute(wr io.Writer, data interface{}) error |
- ExecuteTemplate 方法类似 Execute,但是使用名为 nam e的 t 关联的模板产生输出。
1 | func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error |
模板中插入数据
字段操作:
{{.}}
代表当前对象,可以通过{{.FieldName}}
访问当前对象的字段。输出嵌套字段:
{{with …}}…{{end}}
可以指定当前对象的值,如子结构体。{{range …}}{{end}}
可以循环操作数据。
条件判断:
{{if …}}…{{else if …}}…{{else}}…{{end}}
语句可以进行条件判断。pipelines:在
{{}}
中的都是 pipeline,如{{. | html}}
可以将当前对象进行 HTML 转义,变为 HTML 实体。模板变量:可以通过
$variable := pipeline
方式声明模板局部变量。模板嵌套:
- 声明:
{{define "子模板名称"}}内容{{end}}
- 调用:
{{template "子模板名称"}}
- 声明:
模板函数:
- 每一个模板函数都有一个唯一的名字,可以与一个 Go 函数相关联。FuncMap 类型定义了函数名字符串到函数的映射,每个函数都必须有 1 到 2 个返回值,如果有 2 个则后一个必须是 error 接口类型;如果有 2 个返回值的方法返回的 error 非 nil ,模板执行会中断并返回给调用者该错误。:
1
type FuncMap map[string]interface{}
- 使用
t.Funcs
函数在模板中注册函数:
1
t = t.Funcs(template.FuncMap{"TmplFuncName": FuncName})
- 在模板包内部已经有内置的实现函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14var builtins = FuncMap{
"and": and,
"call": call,
"html": HTMLEscaper,
"index": index,
"js": JSEscaper,
"len": length,
"not": not,
"or": or,
"print": fmt.Sprint,
"printf": fmt.Sprintf,
"println": fmt.Sprintln,
"urlquery": URLQueryEscaper,
}
Must 操作
Must 函数用来检查模板是否正确:
1 | func Must(t *Template, err error) *Template |
一般用于变量初始化:
1 | var t = template.Must(template.New("name").Parse("html")) |