![《Go語言從入門到精通》Go語言中數(shù)據(jù)格式的分析與轉(zhuǎn)換_第1頁](http://file4.renrendoc.com/view/45cfb875e1c11da35cb357399aac3947/45cfb875e1c11da35cb357399aac39471.gif)
![《Go語言從入門到精通》Go語言中數(shù)據(jù)格式的分析與轉(zhuǎn)換_第2頁](http://file4.renrendoc.com/view/45cfb875e1c11da35cb357399aac3947/45cfb875e1c11da35cb357399aac39472.gif)
![《Go語言從入門到精通》Go語言中數(shù)據(jù)格式的分析與轉(zhuǎn)換_第3頁](http://file4.renrendoc.com/view/45cfb875e1c11da35cb357399aac3947/45cfb875e1c11da35cb357399aac39473.gif)
![《Go語言從入門到精通》Go語言中數(shù)據(jù)格式的分析與轉(zhuǎn)換_第4頁](http://file4.renrendoc.com/view/45cfb875e1c11da35cb357399aac3947/45cfb875e1c11da35cb357399aac39474.gif)
![《Go語言從入門到精通》Go語言中數(shù)據(jù)格式的分析與轉(zhuǎn)換_第5頁](http://file4.renrendoc.com/view/45cfb875e1c11da35cb357399aac3947/45cfb875e1c11da35cb357399aac39475.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
Go語言中數(shù)據(jù)格式的分析與轉(zhuǎn)換Go語言從入門到精通了解編程中常用的數(shù)據(jù)交換格式掌握Go語言中JSON格式數(shù)據(jù)的分析與處理01FORMAT02XML03JSONtarget目標掌握Go語言中XML格式數(shù)據(jù)的分析與處理目錄導航10.1常見的數(shù)據(jù)交換格式Contents數(shù)據(jù)交換格式在不同的計算機之間、應用程序之間,通過文件、網(wǎng)絡等各種途徑進行信息交換時,為了雙方都能夠理解而制定的數(shù)據(jù)格式。
數(shù)據(jù)交換格式的基本要求是能夠跨平臺、跨語言得到準確無誤的理解常見的數(shù)據(jù)交換格式純文本
CSV
XML
JSON(及各種變體)YAMLProtoBuf目錄導航10.2XML格式的處理ContentsXML格式
XML是可擴展標記語言(EXtensibleMarkupLanguage)的縮寫簡稱,它被設計為專注于數(shù)據(jù)的表達而非其他(例如數(shù)據(jù)的顯示樣式等)方面,因此特別適合也主要被應用于傳輸數(shù)據(jù)和存儲數(shù)據(jù)XML格式XML格式是基于文本格式之上的,因此,XML文件就是純文本文件的一種。XML文件可以直接用文本編輯軟件打開,其中內(nèi)容也都是由人可以識別的字符組成的。XML數(shù)據(jù)在程序中的表現(xiàn)形式就是一個字符串XML對文本進行了更高級別的格式要求,以便能夠用一定的文本格式規(guī)范來表現(xiàn)出各種類型的數(shù)據(jù)類型和數(shù)據(jù)結構,能夠支持復雜的數(shù)據(jù)類型并且能對數(shù)據(jù)的取值范圍等做出更具體的規(guī)定和限制將數(shù)據(jù)序列化成XML格式引用encoding/xml包//
Person
準備進行XML序列化的表示個人信息的數(shù)據(jù)結構類型type
Person
struct
{
XMLName
xml.Name
`xml:"person"`
Name
string
`xml:"name"`
ID
string
`xml:"id,attr"`
Age
int
`xml:"age"`
Married
bool
Phone
string
`xml:"phone,omitempty"`
Mobile
[]string
`xml:"mobiles>mobile"`
height
float64
`xml:"height"`
AddressType
SecondAddress
AddressType
`xml:"secondAddress"`
Remark
string
`xml:",comment"`}
準備數(shù)據(jù)結構用到的嵌套數(shù)據(jù)結構//
AddressType
表示個人住址的數(shù)據(jù)結構type
AddressType
struct
{
State
string
City
string
Detail
string
PostalCode
string
`xml:"postalCode,attr"`
remark
string}常見類型無需標注進行XML序列化(編碼)person1
:=
&Person{Name:
"張三",
ID:
,
Age:
25,
Married:
false,
Mobile:
[]string{,
},
height:
170,
AddressType:
AddressType{State:
"中國",
City:
"北京",
Detail:
"海淀區(qū)中關村1號",
PostalCode:
"100099",
remark:
"路口右轉(zhuǎn)"},
SecondAddress:
AddressType{State:
"中國",
City:
"上海",
Detail:
"徐匯區(qū)南京路1號",
PostalCode:
"210001",
remark:
"無"},
Remark:
"信息有待完善"}
var
strT
strings.BuilderencoderT
:=
xml.NewEncoder(&strT)errT
:=
encoderT.Encode(person1)if
errT
!=
nil
{
t.Printfln("XML編碼時發(fā)生錯誤:%v",
errT.Error())
return}t.Printfln("XML字符串為:%#v",
strT.String())
outputT,
errT
:=
xml.MarshalIndent(person1,
"
",
"
")if
errT
!=
nil
{
t.Printfln("XML縮進編碼時發(fā)生錯誤:%v",
errT)
return}
os.Stdout.Write(outputT)序列化結果XML字符串為:"<personid=\"postalCode=\"100099\"><name>張三</name><age>25</age><Married>false</Married><mobiles><mobile>lt;/mobile><mobile>lt;/mobile></mobiles><State>中國</State><City>北京</City><Detail>海淀區(qū)中關村1號</Detail><secondAddresspostalCode=\"210001\"><State>中國</State><City>上海</City><Detail>徐匯區(qū)南京路1號</Detail></secondAddress><!--信息有待完善--></person>"<personid=postalCode="100099"><name>張三</name><age>25</age><Married>false</Married><mobiles><mobile>lt;/mobile><mobile>lt;/mobile></mobiles><State>中國</State><City>北京</City><Detail>海淀區(qū)中關村1號</Detail><secondAddresspostalCode="210001"><State>中國</State><City>上海</City><Detail>徐匯區(qū)南京路1號</Detail></secondAddress><!--信息有待完善--></person>進行XML序列化(編碼)person1
:=
&Person{Name:
"張三",
ID:
,
Age:
25,
Married:
false,
Mobile:
[]string{,
},
height:
170,
AddressType:
AddressType{State:
"中國",
City:
"北京",
Detail:
"海淀區(qū)中關村1號",
PostalCode:
"100099",
remark:
"路口右轉(zhuǎn)"},
SecondAddress:
AddressType{State:
"中國",
City:
"上海",
Detail:
"徐匯區(qū)南京路1號",
PostalCode:
"210001",
remark:
"無"},
Remark:
"信息有待完善"}
var
strT
strings.BuilderencoderT
:=
xml.NewEncoder(&strT)errT
:=
encoderT.Encode(person1)if
errT
!=
nil
{
t.Printfln("XML編碼時發(fā)生錯誤:%v",
errT.Error())
return}t.Printfln("XML字符串為:%#v",
strT.String())
outputT,
errT
:=
xml.MarshalIndent(person1,
"
",
"
")if
errT
!=
nil
{
t.Printfln("XML縮進編碼時發(fā)生錯誤:%v",
errT)
return}
os.Stdout.Write(outputT)XML序列化說明1
處理XML格式文本需要使用“encoding/xml”包
Person類型是自定義的用于存儲個人信息的數(shù)據(jù)結構類型
Person結構類型中的大多數(shù)字段(成員變量)后都有一個用于指導如何進行XML序列化的特殊字符串,稱作“標記”(tag),也稱為XML序列化描述字符串,簡稱描述字符串
例如,“Name”字段后用反引號括起來的描述字符串`xml:"name"`,表示Name字段在序列化后的XML中將被轉(zhuǎn)換成名字為“name”的XML元素節(jié)點XML序列化說明2
Person結構中的第一行“XMLNamexml.Name`xml:"person"`”并非定義一個字段,而是結構體中為XML序列化專用的一個設置寫法,用于指定該結構在XML序列化后根節(jié)點的名稱
描述字符串如果是類似`xml:“id,attr”`的形式,則表明該字段將被序列化成為它上級節(jié)點的一個名為“id”的屬性(例子中是Person結構中的ID字段)
描述字符串如果是類似`xml:"phone,omitempty"`的形式,則表示如果該字段有值則將正常序列化為名字為“phone”的XML元素節(jié)點,否則如果是空值(包括各種Go語言中的零值,例如nil)則該節(jié)點將被省略XML序列化說明3描述字符串如果是類似`xml:"mobiles>mobile"的形式,則表示該字段將被序列化成名為mobile的元素節(jié)點,并且放在mobiles元素節(jié)點之內(nèi)成為它的下一級節(jié)點;這種嵌套的級別可以是多級的,例如`xml:"mobiles>mobile>subs“
Person結構中的Mobile字段是[]string類型的,表示一個人可以有多個手機號,結合描述字符串`xml:"mobiles>mobile",這樣序列化出來的XML文本中,將用mobiles節(jié)點下并列的名為“mobile”的XML元素節(jié)點來表示多個手機號;如果描述字符串為`xml:"mobile",則會有多個mobile節(jié)點被直接放在根節(jié)點(即本例中的person節(jié)點)下形如`xml:",comment"`的描述字符串修飾的字段將被序列化成XML中的注釋,將不起數(shù)據(jù)存儲的作用XML序列化說明4沒有加上描述字符串的字段,類似Person結構中的Married字段,將被序列化為與該字段名字一致的XML節(jié)點所有被導出的字段(即大寫字母開頭的字段)才可以被序列化,小寫字母開頭的字段將被忽略,例如本例Person結構中的height字段,雖然后面寫有XML序列化描述字符串,但仍然在序列化后的XML文本中被忽略掉
Person結構中的SecondAddress字段是AddressType類型的,這也是我們在代碼中自定義的一個結構,用于表示個人住址信息;這是結構體中包含復合數(shù)據(jù)類型以及嵌套另一個結構的方法XML序列化說明5
匿名字段:在Person結構中沒有字段名的也是AddressType類型的字段
匿名字段是Go語言中實現(xiàn)類似面向?qū)ο笾小袄^承”概念的重要手段
一個結構體中如果有一個匿名字段,而該匿名字段又是一個結構類型,則該匿名字段所代表結構類型的所有字段會被自動導入到該結構體中引用結構體中匿名字段時,直接用該匿名字段的數(shù)據(jù)類型作為字段名即可XML序列化說明6
AddressType結構類型中的PostalCode字段的XML描述字符串演示了如何在某個子節(jié)點而非根節(jié)點中添加屬性
使用encoding/xml包中的Encoder數(shù)據(jù)類型來做XML的編碼(將數(shù)據(jù)序列化為XMLxml.MarshalIndent函數(shù)可以編碼出帶有縮進的XML文本,返回的是[]byte類型的數(shù)據(jù),需要轉(zhuǎn)換成字符串才能輸出XML序列化說明7
AddressType結構類型中的PostalCode字段的XML描述字符串演示了如何在某個子節(jié)點而非根節(jié)點中添加屬性
使用encoding/xml包中的Encoder數(shù)據(jù)類型來做XML的編碼(將數(shù)據(jù)序列化為XMLxml.MarshalIndent函數(shù)可以編碼出帶有縮進的XML文本,返回的是[]byte類型的數(shù)據(jù),需要轉(zhuǎn)換成字符串才能輸出XML格式的文本反序列化decoderT
:=
xml.NewDecoder(fileT)errT
=
decoderT.Decode(person1)
if
errT
!=
nil
{}
t.Printfln("person1:%#v",
person1)
person2
:=
&Person{}
bytesT,
errT
:=
ioutil.ReadFile(`c:\test\person1.xml`)if
errT
!=
nil
{}
errT
=
xml.Unmarshal(bytesT,
person2)if
errT
!=
nil
{}
t.Printfln("person2:%#v",
person2)XML處理的補充知識1如果在結構體中沒有定義XMLName字段,XML序列化時將以結構名字作為XML文本中根節(jié)點的名稱普通的數(shù)據(jù)類型也可以被進行XML編碼,此時生成的節(jié)點名為該類型的名稱描述字符串為`xml:"-"`的結構體中字段將被忽略描述字符串為`xml:",innerxml"`的字段,將原樣放在XML中而不會被加上標簽(即不會生成XML元素節(jié)點),如果需要標簽則應自行加上XML處理的補充知識2描述字符串為`xml:",chardata"`的字段,也不會生成XML元素節(jié)點,將被作為字符數(shù)據(jù)直接放入描述字符串為`xml:",cdata"`的字段,同樣也不會生成XML元素節(jié)點,而是編碼為XML中的CDATA字符數(shù)據(jù)形式,該形式主要用于放入包含一些特殊字符的文本如果要讓CDATA字符數(shù)據(jù)在XML中放于一個元素節(jié)點之內(nèi),需要定義一個結構類型,例子見下頁:CDATA的應用示例1type
CDATA
struct
{
string
`xml:",cdata"`}type
CodeData
struct
{
CodeName
string
CodeType
string
`xml:",attr"`
CodeDescription
string
`xml:",innerxml"`
CodeData1
[]byte
`xml:",chardata"`
CodeData2
CDATA
Remark
string
`xml:"-"`}CDATA的應用示例2func
main()
{
code1
:=
new(CodeData)
code1.CodeName
=
"測試代碼"
code1.CodeType
=
"Go"
code1.CodeDescription
=
"\n<CodeDescription>本段描述將被原樣保留</CodeDescription>"
code1.CodeData1
=
[]byte{0x65,
0x33,
0x32}
code1.CodeData2
=
CDATA{`for
i
:=
0;
i
<=
18;
i
++
{fmt.Printf("18");}`}
code1.Remark
=
"本段備注將被忽略"
xmlBytesT,
errT
:=
xml.MarshalIndent(code1,
"",
"
")
if
errT
!=
nil
{
t.Printfln("XML編碼時發(fā)生錯誤:%v",
errT)
return
}
t.Printfln("%v",
string(xmlBytesT))}CDATA的應用示例3單個浮點數(shù)的XML:<float64>64.8</float64>code1編碼后的XML:<CodeDataCodeType="Go"><CodeName>測試代碼</CodeName><CodeDescription>本段描述將被原樣保留</CodeDescription>e32<CodeData2><![CDATA[fori:=0;i<=18;i++{fmt.Printf("18");}]]></CodeData2></CodeData>運行結果自行控制某數(shù)據(jù)類型的XML序列化反序列化func
(v
AddressType)
MarshalXML(e
*xml.Encoder,
start
xml.StartElement)
error
{
stringAllT
:=
v.State
+
"|"
+
v.City
+
"|"
+
v.Detail
+
"|"
+
v.PostalCode
+
"|"
+
v.remark
e.EncodeElement(stringAllT,
start)
return
nil}
func
(p
*AddressType)
UnmarshalXML(d
*xml.Decoder,
start
xml.StartElement)
error
{
var
stringBufT
string
d.DecodeElement(&stringBufT,
&start)
listT
:=
strings.Split(stringBufT,
"|")
*p
=
AddressType{State:
listT[0],
City:
listT[1],
Detail:
listT[2],
PostalCode:
listT[3],
remark:
listT[4]}
return
nil}定義在AddressType數(shù)據(jù)類型上目錄導航10.3JSON格式的處理ContentsJSON數(shù)據(jù)格式
JSON格式是數(shù)據(jù)交換格式中使用最廣泛的格式之一,雖然起源于JavaScript語言,但實際應用中已經(jīng)完全實現(xiàn)了跨語言、跨平臺的使用JSON格式最大的特點就是寫法簡單易懂,處理快速,并具備大多數(shù)主要基本數(shù)據(jù)類型的表達能力
Go語言中處理JSON格式的序列化和反序列化與XML相比要簡單很多將數(shù)據(jù)序列化成JSON格式1//
AddressType
表示個人住址的數(shù)據(jù)結構type
AddressType
struct
{
State
string
City
string
Detail
string
PostalCode
string
remark
string}
//
Person
表示個人信息的數(shù)據(jù)結構類型type
Person
struct
{
Name
string
ID
string
Age
int
Married
bool
Phone
string
Mobile
[]string
height
float64
AddressType
SecondAddress
AddressType
Remark
string}數(shù)據(jù)結構一般無需特別處理將數(shù)據(jù)序列化成JSON格式2person1
:=
&Person{Name:
"張三",
ID:
,
Age:
25,
Married:
false,
Mobile:
[]string{,
},
height:
170,
AddressType:
AddressType{State:
"中國",
City:
"北京",
Detail:
"海淀區(qū)中關村1號",
PostalCode:
"100099",
remark:
"路口右轉(zhuǎn)"},
SecondAddress:
AddressType{State:
"中國",
City:
"上海",
Detail:
"徐匯區(qū)南京路1號",
PostalCode:
"210001",
remark:
"無"},
Remark:
"信息有待完善"}
var
strT
strings.BuilderencoderT
:=
json.NewEncoder(&strT)errT
:=
encoderT.Encode(person1)if
errT
!=
nil
{}
t.Printfln("JSON字符串為:%#v",
strT.String())
outputT,
errT
:=
json.MarshalIndent(person1,
"
",
"
")if
errT
!=
nil
{}
os.Stdout.Write(outputT)t.SaveStringToFile(string(outputT),
`c:\test\person1.json`)將數(shù)據(jù)序列化成JSON格式3JSON字符串為:"{\"Name\":\"張三\",\"ID\":\",\"Age\":25,\"Married\":false,\"Phone\":\"\",\"Mobile\":[\",\"],\"State\":\"中國\",\"City\":\"北京\",\"Detail\":\"海淀區(qū)中關村1號\",\"PostalCode\":\"100099\",\"SecondAddress\":{\"State\":\"中國\",\"City\":\"上海\",\"Detail\":\"徐匯區(qū)南京路1號\",\"PostalCode\":\"210001\"},\"Remark\":\"信息有待完善\"}\n"
{"Name":"張三","ID":,"Age":25,"Married":false,"Phone":"","Mobile":[,],"State":"中國","City":"北京","Detail":"海淀區(qū)中關村1號","PostalCode":"100099","SecondAddress":{"State":"中國","City":"上海","Detail":"徐匯區(qū)南京路1號","PostalCode":"210001"},"Remark":"信息有待完善"}將JSON格式的文本反序列化decoderT
:=
json.NewDecoder(fileT)errT
=
decoderT.Decode(person1)if
errT
!=
nil
{}
t.Printfln("person1:%#v",
person1)
person2
:=
&Person{}
bytesT,
errT
:=
ioutil.ReadFile(`c:\test\person1.json`)if
errT
!=
nil
{}
errT
=
json.Unmarshal(bytesT,
person2)if
errT
!=
nil
{}
t.Printfln("person2:%#v",
person2)JSON序列化/反序列化時使用描述字符串type
Person
struct
{
Name
string
`json:"name"`
ID
string
Age
int
`json:",string"`
Married
bool
`json:",omitempty"`
Phone
string
Mobile
[]string
height
float64
`json:"height"`
AddressType
SecondAddress
AddressType
Remark
string
`json:"-"`}與XML類似,JSON也可以加描述字符串特殊說明使用類似`json:"name"`的JSON序列化描述字符串,可以設置該字段在JSON中的鍵(key)名,這也可以突破不使用描述字符串時鍵名必須為大寫字母開頭的限制,這一點在解析網(wǎng)絡上很多JSON接口或文件時非常有用,因為除了Go語言之外,很少有其他語言限制這一點
`json:",string"`這樣的描述字符串一般用于描述數(shù)字類型的字段,表示雖然該字段是數(shù)字,但是也按照字符串形式來編碼控制自定義數(shù)據(jù)類型的JSON序列化/反序列化func
(v
AddressType)
MarshalJSON()
([]byte,
error)
{
stringAllT
:=
v.State
+
"|"
+
v.City
+
"|"
+
v.Detail
+
"|"
+
v.PostalCode
+
"|"
+
v.remark
return
json.Marshal(stringAllT)}
func
(p
*AddressType)
UnmarshalJSON(b
[]byte)
error
{
var
stringBufT
string
errT
:=
json.Unmarshal(b,
&stringBufT)
if
errT
!=
nil
{
return
errT
}
listT
:=
strings.Split(stringBufT,
"|")
*p
=
AddressType{State:
listT[0],
City:
listT[1],
Detail:
listT[2],
PostalCode:
listT[3],
remark:
listT[4]}
return
nil}注意思考兩個函數(shù)為什么一個定義在值上,一個定義在引用上用空接口類型實現(xiàn)復雜結構的JSON序列化map1T
:=
map[string]interface{}{
"Name":
"小明",
"Age":
11,
"Gender":
"男",
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年水電工程招投標代理服務合同
- 2025年帶燈座項目投資可行性研究分析報告
- 制作度服務合同范例
- 2025年度綠色建筑項目施工資料審核承包合同范本
- 車輛出質(zhì)抵押合同范本
- 個人股東合作合同范本
- 2025年三相中頻電源行業(yè)深度研究分析報告
- 臨建混凝土勞務合同范本
- 2025年度工程合同風險預警與防控策略
- 加工彈簧合同范本
- 《工作場所安全使用化學品規(guī)定》
- 2022年菏澤醫(yī)學??茖W校單招綜合素質(zhì)考試筆試試題及答案解析
- 市政工程設施養(yǎng)護維修估算指標
- 課堂嵌入式評價及其應用
- 《管理學基礎》完整版課件全套ppt教程(最新)
- 短視頻:策劃+拍攝+制作+運營課件(完整版)
- 基金會財務報表審計指引
- 藍色卡通風好書推薦教育PPT模板
- 2022年江蘇省泰州市中考數(shù)學試題及答案解析
- 石家莊鐵道大學四方學院畢業(yè)設計46
- 智能化系統(tǒng)培訓
評論
0/150
提交評論