Home > Software design >  How to unmarshall nested XML?
How to unmarshall nested XML?

Time:01-05

I have the following XML file (config-test.xml) that I would to unmarshall:

<configuration version="37">
  <folder id="0usj3" label="aaa" type="sendreceive">
    <device id="U34L32N"></device>
    <device id="U34L32NXX"></device>
    <device id="U34L32NYY"></device>
  </folder>
  <folder id="0usj4" label="bbb" type="sendreceive">
    <device id="U34L32NYY"></device>
  </folder>
  <device id="U34L32N" name="wazaa"></device>
  <device id="FJP7437" name="wazii"></device>
</configuration>

This is the code I am using for that:

package main

import (
    "encoding/xml"
    "fmt"
    "io"
    "os"

    "github.com/rs/zerolog/log"
)

type Device struct {
    ID   string `xml:"id,attr"`
    Name string `xml:"name,attr"`
}

type Folder struct {
    ID     string `xml:"id,attr"`
    Label  string `xml:"label,attr"`
    Type   string `xml:"type,attr"`
    Device []Device
}

type Configuration struct {
    Folder []Folder `xml:"folder"`
    Device []Device `xml:"device"`
}

func main() {
    var err error

    xmlFile, errOpen := os.Open("config-test.xml")
    byteValue, errRead := io.ReadAll(xmlFile)
    if errOpen != nil || errRead != nil {
        log.Fatal().Msgf("cannot open (%v) or read (%v) config.xml: %v", errOpen, errRead)
    }
    defer xmlFile.Close()

    config := Configuration{}
    err = xml.Unmarshal(byteValue, &config)
    if err != nil {
        log.Fatal().Msgf("cannot unmarshall XML: %v", err)
    }

    fmt.Printf("%v", config)
}

I get a partial result:

{[{0usj3 aaa sendreceive []} {0usj4 bbb sendreceive []}] [{U34L32N wazaa} {FJP7437 wazii}]}

It is partial because the XML was parsed correctly, but the <device> entries nested in <folder> were not accounted for.

Is there a special way I should decalre these nested elements?

CodePudding user response:

The annotation is missing on Device in Folder.

type Folder struct {
    ID     string   `xml:"id,attr"`
    Label  string   `xml:"label,attr"`
    Type   string   `xml:"type,attr"`
    Device []Device `xml:"device"`
}
  • Related