使用微信支付的时候遇到这样一种情况:支付成功之后微信会发送一个通知过来,这个通知包含xml格式的数据,其中有一个字段是这样的:
coupon_id_ n , 代 金 券 或 立 减 优 惠 I D , n ,代金券或立减优惠ID, n,代金券或立减优惠ID,n为下标,从0开始编号
n
<xml>
<h:appid xmlns:h="http://www.w3school.com.cn/furniture"><![CDATA[wx2421b1c4370ec43b]]></h:appid>
<attach name="yuanjize"><![CDATA[支付测试]]></attach>
<bank_type>CFT</bank_type>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<mch_id><![CDATA[10000100]]></mch_id>
<nonce_str><![CDATA[<hello>5d2b6c2a8db53831f7eda20af46e531c</hello>]]></nonce_str>
<openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
<out_trade_no><![CDATA[1409811653]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
<sub_mch_id><![CDATA[10000100]]></sub_mch_id>
<time_end><![CDATA[20140903131540]]></time_end>
<total_fee>1</total_fee>
<coupon_fee><![CDATA[10]]></coupon_fee>
<coupon_count><![CDATA[1]]></coupon_count>
<coupon_type><![CDATA[CASH]]></coupon_type>
<coupon_id><![CDATA[10000]]></coupon_id>
<coupon_fee_0><![CDATA[100]]></coupon_fee_0>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
</xml>
func XmlDecode(data string) map[string]string{
decoder := xml.NewDecoder(strings.NewReader(data))
result := make(map[string]string)
key := ""
for{
token, err := decoder.Token() //读取一个标签或者文本内容
if err==io.EOF{
fmt.Println("parse Finish")
return result
}
if err!=nil{
fmt.Println("parse Fail:",err)
return result
}
switch tp := token.(type) { //读取的TOKEN可以是以下三种类型:StartElement起始标签,EndElement结束标签,CharData文本内容
case xml.StartElement:
se := xml.StartElement(tp) //强制类型转换
if se.Name.Local!="xml"{
key=se.Name.Local
}
if len(se.Attr)!=0{ //读取标签属性
fmt.Println("Attrs:",se.Attr)
}
fmt.Println("SE.NAME.SPACE:",se.Name.Space) //读取命名空间
fmt.Println("SE.NAME.LOCAL:",se.Name.Local) //读取标签名称
fmt.Println()
case xml.EndElement:
ee := xml.EndElement(tp)
if ee.Name.Local == "xml"{
return result
}
fmt.Println("EE.NAME.SPACE:",ee.Name.Space)
fmt.Println("EE.NAME.LOCAL:",ee.Name.Local)
case xml.CharData: //文本数据,注意一个结束标签和另一个起始标签之间可能有空格
cd := xml.CharData(tp)
data := strings.TrimSpace(string(cd))
if len(data)!=0{
result[key] = data
fmt.Println(key,",",data)
}
}
}
}
NameXML
命名空间是什么?看一下下面这个例子,
<table>
<leg>4<leg>
<table>
<table>
<tr>
<td>15<td>
<td>16<td>
<tr>
<table>
tabletable
<a:table>
<leg>4<leg>
</a:table>
<b:table>
<tr>
<td>15<td>
<td>16<td>
<tr>
</b:table>
table
Name
type Name struct {
Space, Local string
}
StartElementEndElementNameSpaceLocal
SpaceLocal SpaceLocaltable
CDATACDATACNY]]>CNY CNY hello
最后贴一下上面程序的运行结果:
SE.NAME.SPACE:
SE.NAME.LOCAL: xml
Attrs: [{{xmlns h} http://www.w3school.com.cn/furniture}]
SE.NAME.SPACE: http://www.w3school.com.cn/furniture
SE.NAME.LOCAL: appid
Attrs: [{{ name} yuanjize}]
SE.NAME.SPACE: b
SE.NAME.LOCAL: attach
SE.NAME.SPACE:
SE.NAME.LOCAL: bank_type
SE.NAME.SPACE:
SE.NAME.LOCAL: fee_type
SE.NAME.SPACE:
SE.NAME.LOCAL: is_subscribe
SE.NAME.SPACE:
SE.NAME.LOCAL: mch_id
SE.NAME.SPACE:
SE.NAME.LOCAL: nonce_str
SE.NAME.SPACE:
SE.NAME.LOCAL: openid
SE.NAME.SPACE:
SE.NAME.LOCAL: out_trade_no
SE.NAME.SPACE:
SE.NAME.LOCAL: result_code
SE.NAME.SPACE:
SE.NAME.LOCAL: return_code
SE.NAME.SPACE:
SE.NAME.LOCAL: sign
SE.NAME.SPACE:
SE.NAME.LOCAL: sub_mch_id
SE.NAME.SPACE:
SE.NAME.LOCAL: time_end
SE.NAME.SPACE:
SE.NAME.LOCAL: total_fee
SE.NAME.SPACE:
SE.NAME.LOCAL: coupon_fee
SE.NAME.SPACE:
SE.NAME.LOCAL: coupon_count
SE.NAME.SPACE:
SE.NAME.LOCAL: coupon_type
SE.NAME.SPACE:
SE.NAME.LOCAL: coupon_id
SE.NAME.SPACE:
SE.NAME.LOCAL: coupon_fee_0
SE.NAME.SPACE:
SE.NAME.LOCAL: trade_type
SE.NAME.SPACE:
SE.NAME.LOCAL: transaction_id
parse Finish
参考资料:
XML命名空间:http://www.w3school.com.cn/xml/xml_namespaces.asp
XML CDATA:http://www.w3school.com.cn/xml/xml_cdata.asp
golang XML解析:https://my.oschina.net/solate/blog/724958