Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
生成XML时如何省略GO中的空字段_Xml_Go - Fatal编程技术网

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

生成XML时如何省略GO中的空字段,xml,go,Xml,Go,我有以下结构: 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

我有以下结构:

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仍然包含空的“CustomAttributes”标记吗


一种解决方案是将
CustomAttributes
字段设置为指针。当值为
nil
时,它将被忽略。在文档中查找“零值”

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

我认为这里发生的是,由于您将元素的名称指定为嵌套的,
自定义属性>自定义属性
在某种程度上暗示了“outer”(“intermediate”、“container”)元素,
自定义属性
应该存在,部分原因是没有任何东西可以阻止您使用包含相同外部元素的名称标记任何数量的其他字段,如
自定义属性>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,
    })
}
.

我喜欢这两种解决方案(您的和我接受的答案),它们非常适合学习如何实施,但由于我只能选择一个答案,因此我选择了顶部的答案(基于StackOverflow对它们的排序)。谢谢
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,
    })
}