Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have such xml document and I need to get an array of DATA. I cannot solve this simple task for 4 hours.... want back to node.js :-)

<?xml version="1.0" standalone="no"?>
<RETS ReplyCode="0" ReplyText="Operation Successful" >
<COUNT Records="58951" />
<DELIMITER value="09"/>
<COLUMNS>   LN  </COLUMNS>
<DATA>  09361303    </DATA>
<DATA>  09333085    </DATA>
<MAXROWS/>
                decoder is the error returned by xml.Unmarshal, and you're passing a **Rets to Unmarshal, rather than a *Rets.
– JimB
                Oct 17, 2016 at 20:58
                rdata := new(Rets)  	err = xml.Unmarshal(body, &rdata) 	fmt.Println(rdata)  &{[{} {} {} {} {}] However number of array elements are correct - maybe it is because of spaces in DATA elements?
– Svitlana
                Oct 17, 2016 at 21:03

There are a couple of tools for turning XML into Go structs. One that is suitable for reading is zek (try it online), and although it is experimental, it can deal with a couple of common XML constructs already.

You can go from a XML file (raw) to a struct with a simple command:

$ curl -sL https://git.io/fN4Pq | zek -e -p -c

This will create a struct plus an example program for testing out the marshalling (the example does very little, it read XML from stdin and turns it into JSON).

Here is an example struct (for some XML take from this repo):

// RETS was generated 2018-09-07 12:11:10 by tir on apollo.local.
type RETS struct {
    XMLName       xml.Name `xml:"RETS"`
    Text          string   `xml:",chardata"`
    ReplyCode     string   `xml:"ReplyCode,attr"`
    ReplyText     string   `xml:"ReplyText,attr"`
    METADATATABLE struct {
        Text     string   `xml:",chardata"`
        Resource string   `xml:"Resource,attr"`
        Class    string   `xml:"Class,attr"`
        Version  string   `xml:"Version,attr"`
        Date     string   `xml:"Date,attr"`
        COLUMNS  string   `xml:"COLUMNS"` // MetadataEntryID    SystemNam...
        DATA     []string `xml:"DATA"`    // 7  City        City    Ci ...
    } `xml:"METADATA-TABLE"`

Disclaimer: I wrote zek.

  • If the XML element contains character data, that data is accumulated in the first struct field that has tag ",chardata". The struct field may have type []byte or string. If there is no such field, the character data is discarded.
  • type DATA struct {
        DATA string `xml:",chardata"`
    type Rets struct {
        DATA []DATA `xml:"DATA"`
    

    Or in this simple case, you can just use

    type Rets struct {
        DATA []string `xml:"DATA"`
    

    Which collects the charadata from a list of elements by default

    Wow, Jim. THANK YOU SOOO MUCH! I thought my attempt to switch to go failed on step 1 :-)! – Svitlana Oct 17, 2016 at 21:07 Great, both works. I do not understand fully where chardata came from but I will read docs more :-). Have a great day! – Svitlana Oct 17, 2016 at 21:13

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.