Im not sure this is valid xml, unfortunately its what I'm having to deal with - looking for suggestions on how to accomplish.
my xml looks like this:
<report>
<sort>
<field>type<order>ascending</order></field>
</sort>
</report>
I am attempting to unmarshall into the following structs:
type Sort struct {
Field string `xml:"field"`
Order string `xml:"field>order"`
}
type Report struct {
Sort Sort `xml:"sort"`
}
unfortunately this is throwing the error:
Unmarshalling error: v7.Sort field "Field" with tag "field" conflicts with field "Order" with tag "field>order"
Is there a built in way of achieving this or am I looking at some custom unmarshalling
UPDATE: At least according to this answer it appears this should be valid if slightly ugly xml: Can a XML element contain text and child elements at the same time?
A single XML element can only be mapped to a single struct field, and your model tries to map <field>
to 2 struct fields, so it's not allowed.
The character data of <field>
and the child element <order>
are at the same "level", they are siblings, so they must be in the same struct. But they are different types of nodes: to get the character data, use the xml:",chardata"
struct tag, and to get the value of the <order>
child element, use the xml:"order"
struct tag.
So use the following Go model:
type Field struct {
Value string `xml:",chardata"`
Order string `xml:"order"`
}
type Sort struct {
Field Field `xml:"field"`
}
type Report struct {
Sort Sort `xml:"sort"`
}
Parsing your input XML into this model:
func main() {
var r Report
err := xml.Unmarshal([]byte(src), &r)
fmt.Printf("%+v %v", r, err)
}
const src = `<report>
<sort>
<field>type<order>ascending</order></field>
</sort>
</report>`
Output is (try it on the Go Playground):
{Sort:{Field:{Value:type Order:ascending}}} <nil>
Since Sort
only contains a single Field
field, we can simplify the model to this:
type Field struct {
Value string `xml:",chardata"`
Order string `xml:"order"`
}
type Report struct {
SortField Field `xml:"sort>field"`
}
And it works the same way, gives a similar output (try this one on the Go Playground):
{SortField:{Value:type Order:ascending}} <nil>