Is it possible to decode XML into an interface type with Go 1.3?
For example, if the structs look something like this (simplified):
type Field interface { ... }
// DataField and ControlField satisfy Field interface
type DataField struct { ... } // <- One concrete type, with XML tags
type ControlField struct { ... } // <- Another concrete type, with XML tags
type Record struct {
Fields []Field // <- Field is an interface
}
...
// we want to decode into a record, e.g.
var record Record
decoder.DecodeElement(&record, &se)
...
As far as I can see, it is possible to decode XML with the concrete types, e.g.:
type Record struct {
ControlFields []ControlField // <- Using concrete type works
DataFields []DataField // <- Using concrete type works
}
But the interface type fails, although the implementations are annotated with the correct XML tags.
For a runnable example, see http://play.golang.org/p/tPlw4Y74tt or as gist.
From looking at the code in the encoding/xml
package, it seems, interface types are just skipped:
...
switch v := val; v.Kind() {
case reflect.Interface:
// TODO: For now, simply ignore the field. In the near
// future we may choose to unmarshal the start
// element on it, if not nil.
return p.Skip()
...
Go version: 1.3.
You need to initialize the values inside your interface arrays with some concrete type or xml will not be able to infer to which type are you referring to:
http://play.golang.org/p/6LVgK7rza9
// InterfaceRecord fails
record := InterfaceRecord{
Fields: []Field{&DataField{}},
}
decoder.DecodeElement(&record, &se)
output, err := xml.MarshalIndent(record, " ", " ")
if err != nil {
fmt.Printf("error: %v
", err)
}
os.Stdout.Write(output)
Output:
<record>
<d tag=""></d>
</record>