You’ll see the above xml has attributes set on the user tags, nested elements and if you are able to parse this then you should, by extension, be able to parse any xml file regardless of size.
Reading in our File
The first obstacle we’ll have to overcome is reading this file into memory. We can do this by using a combination of the “os” package and the “io/ioutil” package.
// Open our xmlFile xmlFile, err := os.Open("users.xml") // if we os.Open returns an error then handle it if err != nil { fmt.Println(err) }
fmt.Println("Successfully Opened users.xml") // defer the closing of our xmlFile so that we can parse it later on defer xmlFile.Close()
}
Defining our Structs
Before we can parse our xml file, we need to define some structs. We’ll have one to represent the complete list of users, one to represent our user and then one to represent our users social links.
import ( ... // remember to add encoding/xml to your list of imports "encoding/xml" ... )
// our struct which contains the complete // array of all Users in the file type Users struct { XMLName xml.Name `xml:"users"` Users []User `xml:"user"` }
// the user struct, this contains our // Type attribute, our user's name and // a social struct which will contain all // our social links type User struct { XMLName xml.Name `xml:"user"` Type string`xml:"type,attr"` Name string`xml:"name"` Social Social `xml:"social"` }
// a simple struct which contains all our // social links type Social struct { XMLName xml.Name `xml:"social"` Facebook string`xml:"facebook"` Twitter string`xml:"twitter"` Youtube string`xml:"youtube"` }
Unmarshalling Our XML
So above we’ve seen how to load in our file into memory, in order to marshal it we need to convert this file to a byte array and then use the xml.Unmarshal method in order to populate our Users array.
1 2 3 4 5 6 7 8
// read our opened xmlFile as a byte array. byteValue, _ := ioutil.ReadAll(xmlFile)
// we initialize our Users array var users Users // we unmarshal our byteArray which contains our // xmlFiles content into 'users' which we defined above xml.Unmarshal(byteValue, &users)
// our struct which contains the complete // array of all Users in the file type Users struct { XMLName xml.Name `xml:"users"` Users []User `xml:"user"` }
// the user struct, this contains our // Type attribute, our user's name and // a social struct which will contain all // our social links type User struct { XMLName xml.Name `xml:"user"` Type string`xml:"type,attr"` Name string`xml:"name"` Social Social `xml:"social"` }
// a simple struct which contains all our // social links type Social struct { XMLName xml.Name `xml:"social"` Facebook string`xml:"facebook"` Twitter string`xml:"twitter"` Youtube string`xml:"youtube"` }
funcmain() {
// Open our xmlFile xmlFile, err := os.Open("users.xml") // if we os.Open returns an error then handle it if err != nil { fmt.Println(err) }
fmt.Println("Successfully Opened users.xml") // defer the closing of our xmlFile so that we can parse it later on defer xmlFile.Close()
// read our opened xmlFile as a byte array. byteValue, _ := ioutil.ReadAll(xmlFile)
// we initialize our Users array var users Users // we unmarshal our byteArray which contains our // xmlFiles content into 'users' which we defined above xml.Unmarshal(byteValue, &users)
// we iterate through every user within our users array and // print out the user Type, their name, and their facebook url // as just an example for i := 0; i < len(users.Users); i++ { fmt.Println("User Type: " + users.Users[i].Type) fmt.Println("User Name: " + users.Users[i].Name) fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook) }