You can marshal and untie the map, but you need to write the custom function MarshalXML and UnmarshalXML for your map and give you a map of the type to attach these functions.
Here is an example in which marshals and non-marshals, where the key and value on the map are a string. You can simply change the marshal of the value to int => string and back to unmarshal: https://play.golang.org/p/4Z2C-GF0E7
package main import ( "encoding/xml" "fmt" "io" ) type Map map[string]string type xmlMapEntry struct { XMLName xml.Name Value string `xml:",chardata"` } // MarshalXML marshals the map to XML, with each key in the map being a // tag and it corresponding value being it contents. func (m Map) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if len(m) == 0 { return nil } err := e.EncodeToken(start) if err != nil { return err } for k, v := range m { e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: v}) } return e.EncodeToken(start.End()) } // UnmarshalXML unmarshals the XML into a map of string to strings, // creating a key in the map for each tag and setting it value to the // tags contents. // // The fact this function is on the pointer of Map is important, so that // if m is nil it can be initialized, which is often the case if m is // nested in another xml structurel. This is also why the first thing done // on the first line is initialize it. func (m *Map) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { *m = Map{} for { var e xmlMapEntry err := d.Decode(&e) if err == io.EOF { break } else if err != nil { return err } (*m)[e.XMLName.Local] = e.Value } return nil } func main() { // The Map m := map[string]string{ "key_1": "Value One", "key_2": "Value Two", } fmt.Println(m) // Encode to XML x, _ := xml.MarshalIndent(Map(m), "", " ") fmt.Println(string(x)) // Decode back from XML var rm map[string]string xml.Unmarshal(x, (*Map)(&rm)) fmt.Println(rm) }
source share