1 回答
TA贡献1790条经验 获得超9个赞
正如其他评论所指出的,解码器无法在没有帮助的情况下处理接口字段。xml.Unmarshaller在容器上实现将使它做你想做的事(操场上的完整工作示例):
func (md *MyDoc) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
md.XMLName = start.Name
// grab any other attrs
// decode inner elements
for {
t, err := d.Token()
if err != nil {
return err
}
var i Item
switch tt := t.(type) {
case xml.StartElement:
switch tt.Name.Local {
case "foo":
i = new(Foo) // the decoded item will be a *Foo, not Foo!
case "bar":
i = new(Bar)
// default: ignored for brevity
}
// known child element found, decode it
if i != nil {
err = d.DecodeElement(i, &tt)
if err != nil {
return err
}
md.Items = append(md.Items, i)
i = nil
}
case xml.EndElement:
if tt == start.End() {
return nil
}
}
}
return nil
}
这只是@evanmcdonnal 建议的实现。所有这些都是Item根据下一个令牌的名称实例化正确的,然后d.DecodeElement()用它调用(即让 xml 解码器完成繁重的工作)。
请注意,未编组的Items是指针。如果你想要值,你需要做更多的工作。这还需要进一步扩展以正确处理错误或意外输入数据。
- 1 回答
- 0 关注
- 175 浏览
添加回答
举报