为了账号安全,请及时绑定邮箱和手机立即绑定

生成 XML 时如何省略 GO 中的空字段

生成 XML 时如何省略 GO 中的空字段

Go
Helenr 2022-01-10 15:05:37
我有以下结构:type CustomAttribute struct {    Id     string   `xml:"attribute-id,attr,omitempty"`    Values []string `xml:"value,omitempty"`}type Store struct {    XMLName          xml.Name          `xml:"store"`    Id               string            `xml:"store-id,attr,omitempty"`    Name             string            `xml:"name,omitempty"`    Address1         string            `xml:"address1,omitempty"`    Address2         string            `xml:"address2,omitempty"`    City             string            `xml:"city,omitempty"`    PostalCode       string            `xml:"postal-code,omitempty"`    StateCode        string            `xml:"state-code,omitempty"`    CountryCode      string            `xml:"country-code,omitempty"`    Phone            string            `xml:"phone,omitempty"`    Lat              float64           `xml:"latitude,omitempty"`    Lng              float64           `xml:"longitude,omitempty"`    CustomAttributes []CustomAttribute `xml:"custom-attributes>custom-attribute,omitempty"`}然后我初始化结构如下:    store := &Store{        Id:          storeId,        Name:        row[4],        Address1:    row[5],        Address2:    row[6],        City:        row[7],        PostalCode:  row[9],        StateCode:   row[8],        CountryCode: row[11],        Phone:       row[10],    }所以 CustomAttributes 数组总是空的,而 len(store.CustomAttributes) 是 0 所以知道为什么生成的 XML 仍然包含空的“custom-attributes”标签吗?    <custom-attributes></custom-attributes>
查看完整描述

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"},

        },

    })

}


查看完整回答
反对 回复 2022-01-10
?
温温酱

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,

    })

}


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 229 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号