1

I would like to get a slice of people ([]People) from the following xml:

<file> <person> <name>John Doe</name> <age>18</age> </person> <person> <name>Jane Doe</name> <age>20</age> </person> </file> 

(All other similar questions were too specific and verbose)

3
  • Have you tried anything so far? The XML structure kind of maps onto structs quite easily. You have 1 structure containing several person structures, which you want to map on a slice of Peopletype. Why not wrap []People in a File type? Commented Nov 14, 2018 at 19:34
  • @EliasVanOotegem Yes, I tried several things. One thing I tried I also gave as an answer a few hours before your comment. Is your proposed solution any different to the answer I gave? Commented Nov 15, 2018 at 0:07
  • 1
    Didn't spot that you authored the answer, it's pretty much what I suggested. Usually not a huge fan of anonymous structs, but when (un)marshalling XML, they have their place Commented Nov 16, 2018 at 11:45

1 Answer 1

3

You need to create two structs:

  • one to represent the <file> </file>
  • one for the repeating record <person> </person>

Please see the comments inside the code:

package main import ( "encoding/xml" "fmt" ) var sourceXML = []byte(`<file> <person> <name>John Doe</name> <age>18</age> </person> <person> <name>Jane Doe</name> <age>20</age> </person> </file>`) // Define a structure for each record type Person struct { Name string `xml:"name"` Age int `xml:"age"` } // There needs to be a single struct to unmarshal into // File acts like that one root struct type File struct { People []Person `xml:"person"` } func main() { // Initialize an empty struct var file File err := xml.Unmarshal(sourceXML, &file) if err != nil { fmt.Println(err) } // file.People returns only the []Person rather than the root // file struct with it's contents fmt.Printf("%+v", file.People) } // output: // [{Name:John Doe Age:18} {Name:Jane Doe Age:20}] 

Edit. Kaedys said the File and Person structures can also be nested (using anonymous structs) as follows:

type File struct { People []struct { Name string `xml:"name"` Age int `xml:"age"` } `xml:"person"` } 
Sign up to request clarification or add additional context in comments.

1 Comment

You don't need these to be separate types. You can easily include the 'Person' struct as a nested struct directly within the definition of File. You also should avoid empty literals, file := File{} has the exact same effect and is less readable than var file File (golint will complain about it, too). play.golang.org/p/pCtSsx7LbZD

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.