I'm relatively new to working with golang and I could use some advice on populating a struct tree from an XML file. edit: I fixed an inconsistency with the XML structure vs the struct definitions. Updated the playground link; the full code with a sample XML is at http://play.golang.org/p/1ymyESO2jp .

The XML file has a combination of attributes and values (chardata)

<?xml version="1.0" encoding="UTF-8"?>
<system name="SystemA123" enabled="true" open="9" close="15" timeZone="America/Denver" freq="4h" dailyMax="1" override="false">
    <hosts>
        <host address="10.1.2.3">
            <command>"free -mo</command>
            <command>"cat /proc/cpuinfo | grep processor"</command>
            <command>"ifconfig eth0 down"</command>
            <command>"shutdown -r now"</command>
            <command>"cat /proc/loadavg"</command>
        </host>
        <host address="10.1.2.4">
                  ... more commands>command elements
        </host>

I've build the corresponding structs like so:

type SystemConfig struct {
    XMLName   xml.Name `xml:"system"`
    SysName   string   `xml:"name,attr"`
    Enabled   bool     `xml:"enabled,attr"`
    OpenHour  int      `xml:"open,attr"`
    CloseHour int      `xml:"close,attr"`
    TimeZone  string   `xml:"timeZone,attr"`
    Frequency string   `xml:"freq,attr"` //will use time.ParseDuration to read the interval specified here
    DailyMax  int      `xml:"dailyMax,attr"`
    Override  bool     `xml:"override,attr"`
    Hosts     []*Hosts `xml:"hosts"`
}

type Hosts struct {
    XMLName xml.Name `xml:"hosts"`
    Host    []*Host  `xml:host"`
}

type Host struct {
    XMLName  xml.Name        `xml:"host"`
    IPaddr   string          `xml:"address,attr"`
    Commands []*HostCommands `xml:"command"`
}

type HostCommands struct {
    XMLName xml.Name `xml:"command"`
    Command string   `xml:",chardata"`
}

and I'm reading the XML file into the structs with this code:

var sc *SystemConfig
xmlConf, err := os.Open(appConfFile)
defer xmlConf.Close()
sc, err = ReadSystemConfig(xmlConf)

with this method definition for ReadSystemConfig

func ReadSystemConfig(reader io.Reader) (*SystemConfig, error) {
    sysConf := &SystemConfig{}
    decoder := xml.NewDecoder(reader)
    if err := decoder.Decode(sysConf); err != nil {
        //fmt.Println("error decoding sysConf in ReadSystemConfig: %v", err)
        return nil, err
    }
    return sysConf, nil
}
SystemConfigHostsfmt.Printf("first IP address: %v
", sc.Hosts[0].Host[0].IPaddr
Hi:app pd$ ./app -f ../config/conf.xml
SystemConfig:SysName SystemA123
SystemConfig:Enabled true
SystemConfig:OpenHour 9
SystemConfig:CloseHour 15
SystemConfig:TimeZone America/Denver
SystemConfig:Frequency 4h
SystemConfig:DailyMax 1
SystemConfig:Override false
panic: runtime error: index out of range

goroutine 1 [running]:
runtime.panic(0xd9cc0, 0x1fecf7)
    /usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
main.main()
    /Users/pd/golang/src/local/boxofsand/app/boxofsand.go:95 +0x8ef

I feel like I have the structs setup properly (happy to take advice if I don't); I have tried removing the tags and modifying the code to start from the tags, but I wasn't able to pull any data that way, either (same index out of range error). So, I'm confident that I have borked up 2-3 lines of code here, but I can't find a realistic example online that reads relatively simple, multi-level XML from a file.

Lastly, I'd be open to advice on doing this configuration in JSON instead. I didn't choose that initially because I thought the deeper nesting would be harder to read; also, a lot of what I work with on other projects is XML-based, so I'd like to learn something here that I can apply to those other (for now, Java-based) projects.

As always, thanks in advance for any advice or help you're willing to lend.

edit: I saw a consistency issue in the XML skeleton vs the struct definitions. I modified the XML to suit the structs by removing the tagset