Reputation: 3253
XML with arbitrary number of arbitrarily named elements:
<modules>
<elt1><version>1.2.3</version></elt1>
<eltN><version>4.5.6</version></eltN>
</modules>
How to parse this into a map[string]string
for elementname
to version
? All Unmarshall examples that I found, assume static element names.
Upvotes: 2
Views: 447
Reputation: 20229
You could use xml.Decoder
instead:
Example, which severely lacks error handling.
package main
import (
"encoding/xml"
"fmt"
"io"
"strings"
)
func main() {
data := `<modules>
<elt1><version>1.2.3</version></elt1>
<eltN><version>4.5.6</version></eltN>
</modules>`
fmt.Println(parseVersions(strings.NewReader(data)))
}
func parseVersions(s io.Reader) map[string]string {
r := make(map[string]string)
decoder := xml.NewDecoder(s)
for token, err := decoder.Token(); err == nil; token, err = decoder.Token() {
switch v := token.(type) {
case xml.StartElement:
if el := v.Name.Local; strings.HasPrefix(el, "elt") {
r[el] = parseVersion(decoder)
}
}
}
return r
}
func parseVersion(decoder *xml.Decoder) string {
token, _ := decoder.Token()
switch v := token.(type) {
case xml.StartElement:
if v.Name.Local == "version" {
cd, _ := decoder.Token()
return string(cd.(xml.CharData))
}
}
return ""
}
Upvotes: 3