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

时间:2016-05-12 11:03:28

标签: 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            `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>

2 个答案:

答案 0 :(得分:2)

一种解决方案是使CustomAttributes字段成为指针。当值为nil时,将省略它。寻找&#34;零值&#34;在Auto Complete Drop Down文档中。

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

Marshal

答案 1 :(得分:2)

我认为这里发生的事情是,因为您将元素的名称指定为嵌套,custom-attributes>custom-attribute这意味着“外部”(“中间”?,“容器”?)元素,{{ 1}}应该存在 - 部分是因为没有什么可以阻止你标记任何数量的其他字段,其名称包括相同的外部元素 - 如custom-attributes

跟踪案例没有这些字段被编组,因此不应该使用它们的外部元素对于编组器来说可能太多了 - 我想 - 它是明确编写的,以便在它工作时保持尽可能少的上下文。

因此,虽然我理解你感到困惑,但我认为一旦你眯着眼睛看这种行为是可以理解的。

关于如何解决这个问题,我个人会尝试更加明确 并将切片包装成custom-attributes>foobar类型,与

一样
struct

然后会有一个自定义封送程序:

type CustomAttributes struct {
    XMLName xml.Name `xml:"custom-attributes"`
    Items []CustomAttribute `xml:"custom-attributes>custom-attribute"`
}

Playground link