Iva*_*van 4 xml marshalling go
我正在尝试创建一个实现 MarshalXML 输出的 XML。但目前我面临几个问题。
我用于存储数据的结构是:
type Edition struct {
Launch string `xml:"launch" json:"launch"`
Code string `xml:"code" json:"code"`
Names []NameNode `xml:"names>name"`
Cards CardsComposition `xml:"cards" json:"cards,omitempty"`
Preconstructed PreconstructedInfo `xml:"preconstructed" json:"preconstructed,omitempty"`
Vault *struct{} `xml:"vault" json:"vault"`
Online *struct{} `xml:"online" json:"online"`
}
Run Code Online (Sandbox Code Playgroud)
我想要的是:如果未设置 Preconstructed 字段,请不要放置<preconstructed>
标签(使用标准封送拆收器,即使它为空也将其放置)。
所以我所做的是:
func (preconstructed PreconstructedInfo) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if (PreconstructedInfo{} == preconstructed) {
return nil
}
return e.EncodeElement(preconstructed, start)
}
Run Code Online (Sandbox Code Playgroud)
如果我使用它来编码单个版本实体,它显然有效。但是,如果我尝试对一系列 Edition 实体进行编码,则会出现以下错误:
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
Run Code Online (Sandbox Code Playgroud)
(数组是 ~200 个条目)
所以我不明白的是:
好的,我会回答自己,因为我终于解决了这个问题。
显然,问题之一是 EncodeElement 正在使用 MarshalXML,并且由于文件很大,它会导致函数调用爆炸。
无论如何,解决方案是手动编码元素的所有组件。
所以在那种情况下,我这样做了:
// MarshalXML generate XML output for PrecsontructedInfo
func (preconstructed PreconstructedInfo) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
if (PreconstructedInfo{} == preconstructed) {
return nil
}
if preconstructed.Decks > 0 {
start.Attr = []xml.Attr{xml.Attr{Name: xml.Name{Local: "decks"}, Value: strconv.Itoa(preconstructed.Size)}}
}
if strings.Compare(preconstructed.Type, "") != 0 {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "type"}, Value: preconstructed.Type})
}
err = e.EncodeToken(start)
e.EncodeElement(preconstructed.Size, xml.StartElement{Name: xml.Name{Local: "size"}})
return e.EncodeToken(xml.EndElement{Name: start.Name})
}
Run Code Online (Sandbox Code Playgroud)
所以我所做的是:
这样,它只会在数据可用时生成 xml 标记,并且仅当属性/子项具有值时才添加属性/子项,如果它们为空或 0,则不会添加。
归档时间: |
|
查看次数: |
2793 次 |
最近记录: |