前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go语言学习-xml 解析

go语言学习-xml 解析

作者头像
solate
发布2019-07-22 16:49:14
9410
发布2019-07-22 16:49:14
举报
文章被收录于专栏:solate 杂货铺solate 杂货铺

json xml 解析

xml encoding/xml 包

Xml 做为一种平台无关的数据交换和信息传递技术应用十分广泛。如在 WebService 中 使用 XML 将数据编码成 SOAP 消息。很多接口也使用 XML 来传递数据。

1.func (enc *Encoder) Encode(v interface{}) error可以把一个对像直接序列化到io.Writer对 像中。

2.func (d *Decoder) Decode(v interface{}) error 从 io.Reader 中,返序列化 xml

代码语言:javascript
复制
package main

import (
	"encoding/xml"
	"fmt"
	"os"
)

type Student struct {
	Name string
	Age  int
}

func main() {
	f, err := os.Create("data.dat")
	if err != nil {
		fmt.Println(err)
	}
	defer f.Close()

	s := &Student{"张三", 19} //创建 encode 对像
	encoder := xml.NewEncoder(f)
	//将 s 序列化到文件中
	encoder.Encode(s)

	//重置文件指针到开始位置
	f.Seek(0, os.SEEK_SET)
	decoder := xml.NewDecoder(f)
	var s1 Student //从文件中反序列化成对像
	decoder.Decode(&s1)
	fmt.Println(s1)
}

//data.dat
//<Student><Name>张三</Name><Age>19</Age></Student>

3.func Marshal(v interface{}) ([]byte, error) 对象直接序列化成字符

代码语言:javascript
复制
package main

import (
	"encoding/xml"
	"fmt"
)

type Student struct {
	Name string
	Age  int
}

func main() {
	s := &Student{"张三", 19}
	result, err := xml.Marshal(s)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(result))
}

//<Student><Name>张三</Name><Age>19</Age></Student>

4.func Unmarshal(data []byte, v interface{}) error 将一个 xml 反序列化为对象 结构体中的字段必须是公有的,即大写字母开头的。如果要解析的 xml 是小的,可以 使用 tag 来指定 Struct 的字段与 xml 标记的对应关系

代码语言:javascript
复制
package main

import (
	"encoding/xml"
	"fmt"
)

type Student struct {
	XMLName xml.Name `xml:"student"`
	Name    string   `xml:"name"`
	Age     int      `xml:"age"`
}

func main() {
	str := `<?xml version="1.0" encoding="utf-8"?>
           <student>
<name>张三</name> <age>19</age> </student>`
	var s Student
	xml.Unmarshal([]byte(str), &s)
	fmt.Println(s)
}
  • 结构体的字段还可以跟 Xml 的子结点绑定,如 phones>phone
代码语言:javascript
复制
package main

import (
	"encoding/xml"
	"fmt"
)

type Student struct {
	XMLName xml.Name `xml:"student"`
	Name    string   `xml:"name,attr"`
	Age     int      `xml:"age,attr"`
	Phone   []string `xml:"phones>phone",`
}
type ABC string

func main() {
	str := `<?xml version="1.0" encoding="utf-8"?>
			<student name="张三" age="19">
			   <phones>
				 <phone>12345</phone>
				 <phone>67890</phone>
			   </phones>
			</student>`
	var s Student
	xml.Unmarshal([]byte(str), &s)
	fmt.Println(s)
}


// 如果 带命名空间 <data:student name="张三" age="19">
结果就为 {{data student} 张三 19 []} 

5.token方式,大文件快速

在上面这几种方法中 Token 解析是最快的。对于大文件解析,或对性能有要 求时,这种方法是最佳选择。

代码语言:javascript
复制
package main

import (
	"encoding/xml"
	"fmt"
	"strings"
)

type Student struct {
	Name string
	Age  int
}

func main() {
	str :=
	"<?xml version=\"1.0\" encoding=\"utf-8\"?><Student><Name>张三</Name><Age>19</Age></Student>"
	decoder := xml.NewDecoder(strings.NewReader(str))
	var strName string
	for {
		token, err := decoder.Token()
		if err != nil {
			break
		}
		switch t := token.(type) {
		case xml.StartElement:
			stelm := xml.StartElement(t)
			fmt.Println("Start ", stelm.Name.Local) // 如果带命名空间 stelm.Name.Space
			strName = stelm.Name.Local
		case xml.EndElement:
			endelem := xml.EndElement(t)
			fmt.Println("End ", endelem.Name.Local)
		case xml.CharData:
			data := xml.CharData(t)
			str := string(data)
			switch strName {
			case "Name":
				fmt.Println("姓名:", str)
			case "Age":
				fmt.Println("年龄:", str)
			default:
				fmt.Println("other:", str)
			}
		}
	}
}

xml to struct

将单层xml 属性,转换成struct属性

代码语言:javascript
复制
package main

import (
	"encoding/xml"
	"fmt"
	"strings"
)

func main() {

	str := `<Row SheetId="报告单ID" PatName="患者名称" Age="患者年龄" DeptName=" 科室名称" Sex="患者性别" SheetName="报告名称" SubName="子项目名称" CheckDate="检查日期" VerifyDocName="审核医生" PropDocName="申请医生"ResultStatus="结果状态" RepDocName="报告医生" ReportDate="报告日期"  SheetItemId="报告单ItemID" ItemName="明细项名称" ItemEnName="报告项英文名" Status="高低箭头(↑ ↓)" Indicator="-1:偏低  0:正常 1:偏高 2其他" Value="检查结果值" Unit="检查结果值单位" ValueRange="正常范围" ValueMin="参考最低值" ValueMax="参考最高值" />`

	ChangeXMLToStruct(str)
}

//xml 转换成一个Struct
func ChangeXMLToStruct(str string) {
	decoder := xml.NewDecoder(strings.NewReader(str))
	var strName string
	fmt.Println("strName----", strName)
	for {
		token, err := decoder.Token()
		if err != nil {
			break
		}
		switch t := token.(type) {
		case xml.StartElement:
			//stelm := xml.StartElement(t)
			//fmt.Println("Start ", stelm.Name.Local) // 如果带命名空间 stelm.Name.Space
			//strName = stelm.Name.Local
			//strName = stelm.Name.Space
			//
			//fmt.Println(t.Attr)
			fmt.Println("-------------start---------------")
			for _, attr := range t.Attr {
				formart := "%s  string  `xml:\"%s,attr\"` //%s"
				fmt.Println(fmt.Sprintf(formart, attr.Name.Local, attr.Name.Local, attr.Value))
			}

			fmt.Println("-------------end---------------")

		case xml.EndElement:
			endelem := xml.EndElement(t)
			fmt.Println("End ", endelem.Name.Local)
		case xml.CharData:
			//先不管

		}
	}
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • json xml 解析
    • xml encoding/xml 包
      • xml to struct
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档