G6.1 Go語言中讓XML序列化反序列化支持map[string]string類型

xml包中并不支持某些數(shù)據(jù)類型的XML序列化和反序列化,例如對(duì)map[string]string類型就不支持坯癣,此時(shí)我們可以自行編寫編解碼函數(shù)來補(bǔ)充上對(duì)這種類型的支持霍比。


package main


import (

? "encoding/xml"

? "io"

? t "tools"

)


type StringMap map[string]string


type xmlMapEntry struct {

? XMLName xml.Name

? Value??string `xml:",chardata"`

}


func (va StringMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {

? if len(va) == 0 {

?????? return nil

? }


? errT := e.EncodeToken(start)

? if errT != nil {

?????? return errT

? }


? for k, v := range va {

?????? e.Encode(xmlMapEntry{XMLName:xml.Name{Local: k}, Value: v})

? }


? errT = e.EncodeToken(start.End())


? e.Flush()


? return errT

}


func (p *StringMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {

? *p = StringMap{}


? for {

?????? var e xmlMapEntry


?????? errT := d.Decode(&e)

?????? if errT == io.EOF {

???????????? break

?????? } else if errT != nil {

???????????? return errT

?????? }


?????? (*p)[e.XMLName.Local] = e.Value

? }


? return nil

}


type Students struct {

? Student []StringMap

}


func main() {


? map1T := StringMap{"Name": "小明", "Age": "11", "Gender": "男"}

? map2T := StringMap{"Name": "小紅", "Age": "9", "Gender": "女"}


? students1T := &Students{Student:[]StringMap{map1T, map2T}}


? bytesT, errT := xml.MarshalIndent(students1T,"", "? ")


? if errT != nil {

?????? t.Printfln("XML編碼時(shí)發(fā)生錯(cuò)誤: %v", errT.Error())

?????? return

? }


? t.Printfln("XML: %v",string(bytesT))


? students2T := new(Students)


? errT = xml.Unmarshal(bytesT, &students2T)


? if errT != nil {

?????? t.Printfln("XML解碼時(shí)發(fā)生錯(cuò)誤: %v", errT.Error())

?????? return

? }


? t.Printfln("students2T: %#v",students2T)

}

代碼 10?5 支持map[string]string類型的XML序列化和反序列化


代碼10?5中完整演示了自定義XML編解碼函數(shù)以支持map[string]string類型的序列化和反序列過程腊脱。


-> 首先土砂,我們自定義了一個(gè)類型StringMap,它實(shí)質(zhì)上就是map[string]string類型氮凝,但由于Go語言中不允許在內(nèi)置數(shù)據(jù)類型上定義成員函數(shù)羔巢,所以我們只能用這種方法來新建一個(gè)類型;

->?代碼中StringMap自定義編碼時(shí)用到EncodeToken來寫入包含本字段內(nèi)容的XML標(biāo)簽名,調(diào)用了這個(gè)函數(shù)后竿秆,最好要調(diào)用Encoder.Flush函數(shù)來確保寫入動(dòng)作完畢炭臭;

->?xmlMapEntry結(jié)構(gòu)類型是我們用來進(jìn)行XML編碼時(shí)保存map[string]string中的鍵值對(duì)的專用結(jié)構(gòu),我們會(huì)將鍵名存在該結(jié)構(gòu)中xml.Name類型的字段XMLName的成員變量Local中袍辞,該鍵名對(duì)應(yīng)的數(shù)值則存在xmlMapEntry.Value字段中鞋仍;解碼時(shí)則反向從其中獲取鍵值對(duì);

->?Students結(jié)構(gòu)是為了演示存在多個(gè)StringMap類型的數(shù)據(jù)時(shí)用切片來表示后如何序列化成XML文本的搅吁;


代碼10?5的運(yùn)行結(jié)果是:


XML: <Students> ?

????<Student> ???

????????<Name>小明</Name> ???

????????<Age>11</Age> ???

????????<Gender>男</Gender> ?

????</Student> ?

????<Student> ???

????????<Gender>女</Gender> ???

????????<Name>小紅</Name> ???

????????<Age>9</Age> ?

????</Student>

</Students> ?

---分隔線---

students2T: &main.Students{Student:[]main.StringMap{main.StringMap{"Name":"小明", "Age":"11", "Gender":"男"}, main.StringMap{"Name":"小紅", "Age":"9", "Gender":"女"}}}


可以看出威创,對(duì)map[string]string類型的XML編解碼都被正確地應(yīng)用了,因此我們實(shí)現(xiàn)了Go語言中對(duì)map[string]string類型XML編解碼的支持谎懦。


從前面的這些實(shí)例來看肚豺,Go語言中處理XML序列化與反序列化,理論上結(jié)構(gòu)體中不加任何描述字符串也可以進(jìn)行序列化和反序列化界拦,加入描述字符串則可以較為精細(xì)地進(jìn)行序列化和反序列化吸申,至于更進(jìn)一步的自由控制XML的解析或輸出,需要應(yīng)用xml包中更多的函數(shù)甚至自行編寫處理函數(shù)來進(jìn)行享甸。最后一種方法由于其復(fù)雜性以及生成的XML代碼有可能兼容性不好截碴,除非不得已不太建議使用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛉威,一起剝皮案震驚了整個(gè)濱河市日丹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚯嫌,老刑警劉巖哲虾,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異择示,居然都是意外死亡束凑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門栅盲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汪诉,“玉大人,你說我怎么就攤上這事剪菱∧ο梗” “怎么了拴签?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵孝常,是天一觀的道長。 經(jīng)常有香客問我蚓哩,道長构灸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任岸梨,我火速辦了婚禮喜颁,結(jié)果婚禮上稠氮,老公的妹妹穿的比我還像新娘。我一直安慰自己半开,他們只是感情好隔披,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著寂拆,像睡著了一般奢米。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纠永,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天鬓长,我揣著相機(jī)與錄音,去河邊找鬼尝江。 笑死涉波,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炭序。 我是一名探鬼主播啤覆,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼惭聂!你這毒婦竟也來了城侧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤彼妻,失蹤者是張志新(化名)和其女友劉穎嫌佑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侨歉,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屋摇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幽邓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炮温。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖牵舵,靈堂內(nèi)的尸體忽然破棺而出柒啤,到底是詐尸還是另有隱情,我是刑警寧澤畸颅,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布担巩,位于F島的核電站,受9級(jí)特大地震影響没炒,放射性物質(zhì)發(fā)生泄漏涛癌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拳话。 院中可真熱鬧先匪,春花似錦、人聲如沸弃衍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镜盯。三九已至姜钳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間形耗,已是汗流浹背哥桥。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留激涤,地道東北人拟糕。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像倦踢,于是被迫代替她去往敵國和親送滞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容