I have an XML structure to work with were a part looks like
<Rights>
<Name>NAS</Name>
<Access>2</Access>
<Name>App</Name>
<Access>1</Access>
</Rights>
This is (obviously) a list, and it is guaranteed that it contains of pairs Name, Access
(and always in that particular order). My question: Can I use the encoding/xml
package's Unmarshal
function to unmarshal Name
and Access
in a single struct?
Consider the following example:
package main
import (
"encoding/xml"
"fmt"
)
var XML = []string{`
?xml version="1.0" encoding="UTF-8"?>
<SessionInfo>
<SID>abc123</SID>
<Rights>
<Name>NAS</Name>
<Access>2</Access>
<Name>App</Name>
<Access>1</Access>
</Rights>
</SessionInfo>
`,`
<SessionInfo>
<SID>def456</SID>
<Rights />
</SessionInfo>
`}
type Right struct {
Name string
Access int
}
type SessionInfo struct {
XMLName xml.Name `xml:"SessionInfo"`
SID string
Rights []Right
}
func main() {
for _,entry := range XML {
info := SessionInfo{}
if err := xml.Unmarshal([]byte(entry), &info); err != nil {
fmt.Println("Marshal failed", err.Error())
continue
}
fmt.Printf("%+v
", info)
}
}
This doesn't work as expected:
// Only the first value is found
{SID:abc123 Rights:[{Name:App Access:1}]}
// One (not existing) value was found and the struct's zero value was used
{SID:def456 Rights:[{Name: Access:0}]}
I could (and this works) define the properties independent of each other like
Names []string `xml:"Rights>Name"`
Accesses []int `xml:"Rights>Access"`
But I'd prefer the structure format of the first version without converting them manually.
Is there a way to get the expected result?