2 回答
TA贡献1799条经验 获得超8个赞
一种解决方案是使CustomAttributes字段成为指针。值为 时将省略nil。在Marshal文档中查找“零值” 。
package main
import (
"encoding/xml"
"fmt"
"log"
)
type Store struct {
XMLName xml.Name `xml:"store"`
CustomAttributes *[]CustomAttribute `xml:"custom-attributes>custom-attribute,omitempty"`
}
type CustomAttribute struct {
Id string `xml:"attribute-id,attr,omitempty"`
Values []string `xml:"value,omitempty"`
}
func print(store *Store) {
data, err := xml.Marshal(store)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
}
func main() {
print(&Store{})
print(&Store{
CustomAttributes: &[]CustomAttribute{},
})
print(&Store{
CustomAttributes: &[]CustomAttribute{
{Id: "hello"},
},
})
}
TA贡献1752条经验 获得超4个赞
我认为这里发生的情况是,由于您将元素的名称指定为嵌套的,custom-attributes>custom-attribute那种暗示custom-attributes应该存在“外部”(“中间”?,“容器”?)元素- 部分原因是没有什么可以阻止你从使用包含相同外部元素的名称标记任意数量的其他字段 - 例如custom-attributes>foobar.
跟踪没有一个这样的字段被封送的情况,因此它们的外部元素不应该被使用对于封送处理程序来说可能太多了——我想——被明确地写成在它工作时尽可能少地保留上下文。
因此,虽然我理解您对此感到困惑,但我认为这种行为在您眯着眼睛看久一点之后是可以理解的。
至于如何解决它,我个人会尝试更加明确并将您的切片包装成一种struct类型,例如
type CustomAttributes struct {
XMLName xml.Name `xml:"custom-attributes"`
Items []CustomAttribute `xml:"custom-attributes>custom-attribute"`
}
然后会有一个自定义编组器:
func (cas CustomAttributes) MarshalXML(e *xml.Encoder,
start xml.StartElement) (err error) {
if len(cas.Items) == 0 {
return nil
}
err = e.EncodeToken(start)
if err != nil {
return
}
err = e.Encode(cas.Items)
if err != nil {
return
}
return e.EncodeToken(xml.EndElement{
Name: start.Name,
})
}
- 2 回答
- 0 关注
- 229 浏览
添加回答
举报
