golang - 如何让自定义类型(string)在xml.Marshal下生成CDATA格式
本文介绍了golang - 如何让自定义类型(string)在xml.Marshal下生成CDATA格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
微信消息回复要求这样的格式,cdata是为了解析特殊字符:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
使用golang实现该规范时发现新版xml.Marshal()可以利用用struct标签xml:",cdata"
实现cdata编码,但是要定义一个struct来处理了,代码实现:
package main
import (
"encoding/xml"
"fmt"
"time"
)
type TextMsg struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA
FromUserName CDATA
CreateTime int64
MsgType CDATA
Content CDATA
}
type CDATA struct {
Text string `xml:",cdata"`
}
func main() {
msg := TextMsg{
ToUserName: CDATA{"userId"},
FromUserName: CDATA{"appId"},
CreateTime: time.Now().Unix(),
MsgType: CDATA{"text"},
Content: CDATA{"some message like <hello>"}}
b, _ := xml.MarshalIndent(msg, "", " ")
fmt.Println(string(b))
}
输出结果:
<xml>
<ToUserName><![CDATA[userId]]></ToUserName>
<FromUserName><![CDATA[appId]]></FromUserName>
<CreateTime>1485837083</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[some message like <hello>]]></Content>
</xml>
但我觉得不完美,因为赋值时不如普通的string类型那样方便,于是将CDATA改成string类型,并尝试实现MarshalXML():
package main
import (
"encoding/xml"
"fmt"
"time"
)
type TextMsg struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA
FromUserName CDATA
CreateTime int64
MsgType CDATA
Content CDATA
}
type CDATA string
func (c CDATA) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
e.EncodeElement("<![CDATA["+string(c)+"]]>", start)
return nil
}
func main() {
msg := TextMsg{
ToUserName: "userId",
FromUserName: "appId",
CreateTime: time.Now().Unix(),
MsgType: "text",
Content: "some message like <hello>"}
b, _ := xml.MarshalIndent(msg, "", " ")
fmt.Println(string(b))
}
但是输出结果并不符合预期,尖括号被转义了:
<xml>
<ToUserName><![CDATA[userId]]></ToUserName>
<FromUserName><![CDATA[appId]]></FromUserName>
<CreateTime>1485837470</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[some message like <hello>]]></Content>
</xml>
那么问题来了,如何能实现自定义类型正常解析成CDATA,希望大家畅所欲言~!
解决方案
此问题已解决:
func (c CDATA) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
return e.EncodeElement(struct {
string `xml:",cdata"`
}{string(c)}, start)
}
这篇关于golang - 如何让自定义类型(string)在xml.Marshal下生成CDATA格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文