2016-05-12 38 views
2

時如何省略走空場,我有以下結構:生成XML

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> 

回答

1

一個解決方案是使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"}, 
     }, 
    }) 
} 

Playground

2

我想在這裏發生的是,因爲你指定的元素的名稱嵌套,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, 
    }) 
} 

Playground link

+0

我喜歡這兩種解決方案(你和我接受的答案),他們很好學習如何實現,但因爲我只能選擇一個答案,我選擇了頂部的答案(根據StackOverflow如何排序)。謝謝。 – daniels