2014-12-02 7 views
7

Dopo un po 'di tracce e di errori mi piacerebbe condividere il problema che sto trattando.Golang Nascondi tag genitore XML se vuoto

Sto compilando una struct e la converto in XML (xml.Marshal) Come puoi vedere sotto l'esempio di Foo funziona come previsto. L'esempio Bar tuttavia crea un gruppo vuoto1.

Quindi la mia domanda è: "Come faccio a evitare che Group1 venga generato se non ci sono figli impostati".

package main 

import (
    "fmt" 
    "encoding/xml" 
) 

type Example1 struct{ 
    XMLName xml.Name `xml:"Example1"` 
    Element1 string `xml:"Group1>Element1,omitempty"` 
    Element2 string `xml:"Group1>Element2,omitempty"` 
    Element3 string `xml:"Group2>Example3,omitempty"` 
} 

func main() { 
    foo := &Example1{} 
    foo.Element1 = "Value1" 
    foo.Element2 = "Value2" 
    foo.Element3 = "Value3" 

    fooOut, _ := xml.Marshal(foo) 
    fmt.Println(string(fooOut)) 

    bar := &Example1{} 
    bar.Element3 = "Value3" 
    barOut, _ := xml.Marshal(bar) 
    fmt.Println(string(barOut)) 
} 

Foo uscita:

Bar in uscita:

<Example1> 
    <Group1></Group1> <------ How to remove the empty parent value ? 
    <Group2> 
     <Example3>Value3</Example3> 
    </Group2> 
</Example1> 

aggiunta

Inoltre ho provato a fare quanto segue, ma genera ancora un vuoto "Gruppo1" :

type Example2 struct{ 
    XMLName xml.Name `xml:"Example2"` 
    Group1 struct{ 
     XMLName xml.Name `xml:"Group1,omitempty"` 
     Element1 string `xml:"Element1,omitempty"` 
     Element2 string `xml:"Element2,omitempty"` 
    } 
    Element3 string `xml:"Group2>Example3,omitempty"` 
} 

Il codice completo può essere trovato qui: http://play.golang.org/p/SHIcBHoLCG. esempio per

EDIT: cambiato l'esempio golang da utilizzare MarshalIndent per migliorare la leggibilità

Edit 2 L'esempio da Ainar-G Funziona bene per nascondere il genitore vuoto, ma popolamento lo rende molto più difficile. "panic: runtime error: invalid memory address or nil pointer dereference"

risposta

11

Example1 non funziona perché a quanto pare il tag ,omitempty funziona solo sull'elemento stesso e non sugli elementi di inclusione a>b>c.

Example2 non funziona perché ,omitempty non riconosce le strutture vuote come vuote. From the doc:

The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero.

Nessuna menzione di struttura. È possibile effettuare il lavoro baz esempio cambiando Group1 ad un puntatore ad una struct:

type Example2 struct { 
    XMLName xml.Name `xml:"Example1"` 
    Group1 *Group1 
    Element3 string `xml:"Group2>Example3,omitempty"` 
} 

type Group1 struct { 
    XMLName xml.Name `xml:"Group1,omitempty"` 
    Element1 string `xml:"Element1,omitempty"` 
    Element2 string `xml:"Element2,omitempty"` 
} 

Quindi, se si vuole riempire Group1, è necessario allocare separatamente:

foo.Group1 = &Group1{ 
    Element1: "Value1", 
} 

Esempio : http://play.golang.org/p/mgpI4OsHf7

+0

Puoi spiegare perché funziona con un puntatore? Non riesci a trovare alcun riferimento nei documenti su questo. – DonSeba

+0

Ora, quando provo a popolare la struct ottengo il seguente: 'panico: errore di runtime: indirizzo di memoria non valido o puntatore nullo dereferenziazione 'su quale soluzione? – DonSeba

+0

@DonSeba Ho dato [il link] (http://golang.org/pkg/encoding/xml/#Marshal) nella mia risposta. ', omitempty' funziona per tutto tranne che per le struct. Non conosco la ragione esatta, suppongo che abbia qualcosa a che fare con i limiti di riflessione in Go. –