Skip to content

Instantly share code, notes, and snippets.

@mpdroog
Last active June 3, 2021 17:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpdroog/b167994a90f8cdb8ad683f909b4ca678 to your computer and use it in GitHub Desktop.
Save mpdroog/b167994a90f8cdb8ad683f909b4ca678 to your computer and use it in GitHub Desktop.
golang XML map[string]string encode/decode
// https://stackoverflow.com/questions/30928770/marshall-map-to-xml-in-go
// https://stackoverflow.com/questions/33486725/golang-xml-unmarshal-interface-types
package main
import (
"fmt"
"encoding/xml"
)
// StringMap is a map[string]string.
type StringMap map[string]string
// StringMap marshals into XML.
func (s StringMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
tokens := []xml.Token{start}
for key, value := range s {
t := xml.StartElement{Name: xml.Name{"", key}}
tokens = append(tokens, t, xml.CharData(value), xml.EndElement{t.Name})
}
tokens = append(tokens, xml.EndElement{start.Name})
for _, t := range tokens {
err := e.EncodeToken(t)
if err != nil {
return err
}
}
// flush to ensure tokens are written
return e.Flush()
}
func (s StringMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err != nil {
return err
}
switch tt := t.(type) {
case xml.StartElement:
key := tt.Name.Local
val := ""
if err := d.DecodeElement(&val, &tt); err != nil {
return err
}
s[key] = val
case xml.EndElement:
if tt.Name == start.Name {
return nil
}
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment