Processing XML for Go-web programming

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Open Source Book excerpt from Astaxie

Build-web-application-with-golang

The following example operates with the information described in XML below.

<?xml version="1.0" encoding="utf-8"? ><servers version="1">    <server>        <servername>shanghai_vpn</ servername>        <serverIP>127.0.  0.1</serverIP>    </server>    <server>        <servername>beijing_vpn</ servername>        <serverIP>127.0.  0.2</serverIP>    </server></servers>

Parsing xml

1. Parse the XML file with the function of the XML packet Unmarshal .

func unmarshal (data []byte, v interface{}) Error Data is the received XML stream; Interface () is the structure to output. Currently only supports struct,slice,string.
Package main Import ("Encoding/xml"    "FMT"    "Io/ioutil"    "OS") Type Recurlyserversstruct{xmlname XML. Name ' xml:"Servers"`//<code>xml: "ServerName" </code><span style= "color: #333333; font-family:helvetica, Arial, FreeSans , clean, sans-serif;font-size:13.63636302947998px;line-height:20px;background-color: #FFFFFF; " > Called Strcut tag</span> Version string ' xml: ' version,attr 'Svs []server ' xml:"Server"' Descriptionstring' XML:", InnerXml"'} type serverstruct{xmlname XML. Name ' xml:"Server"' ServerNamestring' XML:"ServerName"' ServerIPstring' XML:"ServerIP"'} func main () {file, err:= OS. Open ("Servers.xml")//For Read access.defer file. Close ()ifErr! =Nil {fmt. Printf ("Error:%v", Err)return} data, err:=Ioutil. ReadAll (file)ifErr! =Nil {fmt. Printf ("Error:%v", Err)return} V:=recurlyservers{} Err= XML. Unmarshal (Data, &v)ifErr! =Nil {fmt. Printf ("Error:%v", Err)return} fmt. Println (v)}

The following are the output results:

{{servers} 1 [{{server} Shanghai_vpn 127.0.0.1} {{server} Beijing_vpn 127.0.0.2}]<server>    < Servername>shanghai_vpn</servername>    <serverIP>127.0.0.1</serverIP></server> <server>    <serverName>Beijing_VPN</serverName>    <serverip>127.0.0.2</serverip ></server>}

But now there is a question, how does the Unmarshal method correspond to the elements of XML and the attributes of strut? This is due to the fact that there is a priority to the read process.

First: The Unmarshal method will be based on the strut tag in the strut to find the corresponding property, if found to assign a value to the property;

Otherwise: The Unmarshal method will find the corresponding attribute in the strut based on the element name;

It is important to note that the tag, field name, and XML element are case-sensitive when parsing, so you must have one by one corresponding fields.

The following rules are followed when parsing XML into a struct:

If the field of a struct is a string or []byte type and its tag contains ",innerxml" , Unmarshal will add all the embedded raw XML in the element corresponding to this field to this field, as defined in the example above description. The final output is

shanghai_vpn127.0.0.1beijing_vpn127.0.0.2

If there is one in the struct called XMLName, and the type is XML. Name field, the name of the element is saved to the field at the time of parsing, as in the example above servers.

If the tag definition of a struct field contains the name of element in the XML structure, then the corresponding element value is assigned to the field, as defined on servername and ServerIP.

If the tag of a struct field is defined, then the value of the element corresponding to the field of the struct is ",attr" assigned to the field, as defined in the previous version, when parsing.

If the tag definition of a struct field is the "a>b>c" same, the value of the C element below B of the XML structure A is assigned to the field when parsing.

If the tag of a struct field is defined "-" , no XML data will be parsed for that field.

If the tag that follows the struct field is defined ",any" , the child element matches the field if it does not satisfy the other rules.

If an XML element contains one or more comments, then these comments will be added to the first tag containing ", Comments" field, the type of the field may be []byte or string, if no such field exists, then the comment will be discarded.

Well, I've finally finished the rules. Although more, but the code when the attention point is familiar.

Output XML

The XML package provides a MarshalAnd MarshalIndentTwo functions to meet our needs. The main difference between the two functions is that the second function increases the prefix and indentation, and the function is defined as follows:   func Marshal(v interface{}) ([]byte, error) func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)The first parameter of the two functions is the structure-defined type data that is used to generate the XML, and the return value is the XML data stream.

The code for generating the above XML is as follows:

Package MainImport (    "Encoding/xml"    "FMT"    "OS") type Servers struct {xmlname XML. Name ' xml:"Servers"' Version string ' xml:"version,attr"' Svs []server ' xml:"Server"'} type server struct {ServerName string ' xml:"ServerName"' ServerIP string ' xml:"ServerIP"'} func main () {V:= &servers{version:"1"} V.svs= Append (V.svs, server{"Shanghai_vpn","127.0.0.1"}) V.svs= Append (V.svs, server{"Beijing_vpn","127.0.0.2"}) output, err:= XML. Marshalindent (V,"  ","    ")    ifErr! =Nil {fmt. Printf ("Error:%v\n", Err)} Os. Stdout.write ([]byte (XML. Header)) OS. Stdout.write (Output)}

The reason os.Stdout.Write([]byte(xml.Header)) This code appears is because xml.MarshalIndent or the xml.Marshal output of the information is not with the XML header, in order to generate the correct XML file, we used the XML package predefined header variables.

We see that the Marshal function receives the parameter V is interface{} type, that is, it can accept any type of argument, then the question is, in the XML package, according to what rules to generate the corresponding XML file?

    • If V is an array or slice, then output each element, like value
    • If V is a pointer, then the contents of the pointer are marshal, and if the pointer is empty, nothing is output
    • If V is interface, then the data contained in the interface is processed
    • If V is a different data type, it will output the field information owned by this data type

What determines the name of the element in the generated XML file? The element name is obtained from the struct by the following precedence:

    • If V is the name defined in the tag of Struct,xmlname
    • Type is XML. The value of the field named XMLName of name
    • Get by the tag of the field in Strcut
    • Use the Strcut field name to get
    • Type name of the Marshall

How do we set the tag information for a field in a struct to control the final XML file generation?

    • XMLName will not be output
    • the field containing "-" does not output
    • tag with "Name,attr" , with name as the property name, The field value is output as a property of this XML element, as described in the
    • tag in the previous version field, which contains ", attr" , which is output as an attribute of the XML element as the property name of the struct's field name, like the previous one, Just this name is the field name by default. The
    • tag contains ", Chardata" , and the output is XML character data, not element. The
    • tag contains ", InnerXml" , and will be output as is, without the usual encoding process
    • tag contains ", comment" , will be exported as an XML comment without a regular encoding process, and the field value cannot contain the "--" string
    • tag with "Omitempty" , and if the value of the field is null then the field will not be output to XML. Null values include: false, 0, nil pointer, or nil interface, any array of length 0, slice, map, or string
    • Tag containing "A>b>c" , Then the loop output of three elements a contains b,b contains C, for example, the following code will output

FirstName string   ' xml:'name>first'' LastName  string   ' xml:  "name>last"'

Above we described how to use the Go language XML package to encode/decode the XML file, it is important that all XML operations are implemented through the struct tag, so learning to use the struct tag becomes very important, in the article we briefly enumerated how to define the tag. For more content or tag definitions, please refer to the appropriate official information.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.