Go使用etree解析XML

Go使用etree解析XML


1、简单了解xml

通过下图对xml中的元素和属性有简单了解:

  • 1、尖括号括起来的内容是元素
  • 2、通过元素名称建立xml路径,比如Preset的路径:/Envelop/Body/GetPresetsResponse
  • 3、元素可能带有属性,比如Preset元素带有属性token
  • 4、而属性有属性值

简单的xml例子:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tst="http://www.onvif.org/ver10/storage/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:dn="http://www.onvif.org/ver10/network/wsdl" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12" xmlns:http="http://schemas.xmlsoap.org/wsdl/http" xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:wsadis="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2" xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:tnshik="http://www.hikvision.com/2011/event/topics" xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema" xmlns:tas="http://www.onvif.org/ver10/advancedsecurity/wsdl" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:axt="http://www.onvif.org/ver20/analytics">
	<env:Body>
		<tptz:GetPresetsResponse>
			<tptz:Preset token="1">
				<tt:Name>预置点 1</tt:Name>
				<tt:PTZPosition>
					<tt:PanTilt x="0.847167" y="0.531368"/>
					<tt:Zoom x="0.000000"/>
				</tt:PTZPosition>
			</tptz:Preset>
			<tptz:Preset token="2">
				<tt:Name>预置点 2</tt:Name>
				<tt:PTZPosition>
					<tt:PanTilt x="0.964722" y="0.085474"/>
					<tt:Zoom x="0.000000"/>
				</tt:PTZPosition>
			</tptz:Preset>
			<tptz:Preset token="3">
				<tt:Name>预置点3</tt:Name>
				<tt:PTZPosition>
					<tt:PanTilt x="0.847167" y="0.531368"/>
					<tt:Zoom x="0.000000"/>
				</tt:PTZPosition>
			</tptz:Preset>
        </tptz:GetPresetsResponse>
	</env:Body>
</env:Envelope>

元素和属性分析:

在这里插入图片描述

2、Go语言使用etree解析xml

etree可以像解析json一样方便的解析xml:(etree地址:https://pkg.go.dev/github.com/beevik/etree)

  • 1、读取xml
  • 2、通过路径找到元素和属性
  • 3、获取属性值或元素值。

比如解析上面的xml文件,总体代码如下:

doc := etree.NewDocument()
if err := doc.ReadFromString(message); err != nil {
    return returnInfo{GetPresetByTokenErr, "read xml failed."}
}
root := doc.SelectElement("Envelope")
if root == nil {
    return returnInfo{GetPresetByTokenErr, "read xml failed."}
}
token := root.FindElements("./Body/GetPresetsResponse/Preset")
if token == nil {
    return returnInfo{GetPresetByTokenErr, "read xml failed."}
}

for _, res := range token {
    fmt.Println(res.SelectAttr("token").Value)
    fmt.Println(res.FindElement("./Name").Text())
}

然后我们分布理解:

(1)、读取xml

可以从文件读取或者直接读取字符串

doc := etree.NewDocument()
if err := doc.ReadFromString(message); err != nil {
    return returnInfo{GetPresetByTokenErr, "read xml failed."}
}
(2)、通过路径找到元素或属性位置

设置根节点,然后从根节点开始寻找和设置要便利的元素节点:

root := doc.SelectElement("Envelope")
if root == nil {
	return returnInfo{GetPresetByTokenErr, "read xml failed."}
}
token := root.FindElements("./Body/GetPresetsResponse/Preset")
if token == nil {
	return returnInfo{GetPresetByTokenErr, "read xml failed."}
}
(3)、对于多个同名元素节点

使用etree中的接口时获取元素值时在find element找到元素路径后获取元素的text值即可:

fmt.Println(res.FindElement("./Name").Text())

而对于属性值则需要选中属性attr值获取属性的value:

fmt.Println(res.SelectAttr("token").Value)

然后循环每个元素节点,然后分别获取对应元素节点的属性值和其子元素的元素值:

for _, res := range token {
    fmt.Println(res.SelectAttr("token").Value)
    fmt.Println(res.FindElement("./Name").Text())
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值