Consider the following struct:
type MyStruct struct {
Name string
Meta map[string]interface{}
}
Which has the following UnmarshalXML function:
func (m *MyStruct) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var v struct {
XMLName xml.Name //`xml:"myStruct"`
Name string `xml:"name"`
Meta struct {
Inner []byte `xml:",innerxml"`
} `xml:"meta"`
}
err := d.DecodeElement(&v, &start)
if err != nil {
return err
}
m.Name = v.Name
myMap := make(map[string]interface{})
// ... do the mxj magic here ... -
temp := v.Meta.Inner
prefix := "<meta>"
postfix := "</meta>"
str := prefix + string(temp) + postfix
//fmt.Println(str)
myMxjMap, err := mxj.NewMapXml([]byte(str))
myMap = myMxjMap
// fill myMap
//m.Meta = myMap
m.Meta = myMap["meta"].(map[string]interface{})
return nil
}
My problem with this code is these lines:
prefix := "<meta>"
postfix := "</meta>"
str := prefix + string(temp) + postfix
myMxjMap, err := mxj.NewMapXml([]byte(str))
myMap = myMxjMap
//m.Meta = myMap
m.Meta = myMap["meta"].(map[string]interface{})
My question is how I make the correct use of the xml annotations (,innerxml etc), fields and structs, so I don't have to manually pre-/append the <meta></meta>
tags afterwards to get the whole Meta field as a single map.
The full code example is here: http://play.golang.org/p/Q4_tryubO6
The JAXB Unmarshaller interface is responsible for governing the process of deserializing the XML data to Java Objects. The unmarshalling to objects can be done to variety of input sources. 1. How to unmarshal XML to Object 1.1. Create Unmarshaller Generally, to create Unmarshaller you can reuse this code. 1.2. Unmarshalling from an InputStream
The first line of the struct declares the XMLName which is essentially the XML tag. Child elements are the Description, Title, and Link which are again essentially the XML tags associated with the data. The Channel field of the struct refers to another struct so this amounts to a field in the Rss struct.
This maps a class or an enum type to an XML root element. When a top-level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document. //.... It defines the fields or properties of your Java classes that the JAXB engine uses for including into generated XML.
Maps a field or property to the text value on an XML tag. Maps a collection to a list of values separated by space. This maps a class or an enum type to an XML root element. When a top-level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document. //....
xml
package doesn't provide a way to unmarshal XML into map[string]interface{}
because there is no single way to do it and in some cases it is not possible. A map doesn't preserve order of the elements (that is important in XML) and doesn't allow elements with duplicate keys.
mxj
package that you used in your example has some rules how to unmarshal arbitrary XML into Go map. If your requirements do not conflict with these rules you can use mxj
package to do all parsing and do not use xml
package at all:
// I am skipping error handling here
m, _ := mxj.NewMapXml([]byte(s))
mm := m["myStruct"].(map[string]interface{})
myStruct.Name = mm["name"].(string)
myStruct.Meta = mm["meta"].(map[string]interface{})
Full example: http://play.golang.org/p/AcPUAS0QMj
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With