5

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/>

type DATA struct {
    DATA string `xml:"DATA"`
}

type Rets struct {
    DATA []DATA `xml:"RETS>DATA"`
}


data := &Rets{}
decoder := xml.Unmarshal(body,&data)

fmt.Println(decoder)
4
  • 1
    decoder is the error returned by xml.Unmarshal, and you're passing a **Rets to Unmarshal, rather than a *Rets. Commented Oct 17, 2016 at 20:58
  • sorry, of course fmt.Println(data), but I got an empty object Commented Oct 17, 2016 at 20:58
  • However, number of elements are correct, but they are empty. Commented Oct 17, 2016 at 21:00
  • 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? Commented Oct 17, 2016 at 21:03

2 Answers 2

9

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.

Sign up to request clarification or add additional context in comments.

Comments

3

From the xml.Unmarshal docs

  • 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.

Use

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

2 Comments

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.