2014-12-02 7 views
7

Nach einigem Trail und Fehler möchte ich das Problem, mit dem ich es zu tun habe, teilen.Golang Hide XML-Eltern-Tag, wenn leer

Ich bevölke eine Struktur und konvertiere sie in ein XML (xml.Marshal) Wie Sie unten sehen können, funktioniert das Foo Beispiel wie erwartet. Das Bar-Beispiel erstellt jedoch eine leere Gruppe1.

Meine Frage ist also: "Wie verhindere ich, dass Group1 generiert wird, wenn keine Kinder eingestellt sind."

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 Ausgang:

Bar Ausgang:

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

Zusatz

Zusätzlich habe ich versucht, die folgende tun, sondern erzeugt immer noch eine leere "Gruppe1" :

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

Der vollständige Code kann hier gefunden werden: http://play.golang.org/p/SHIcBHoLCG. Beispiel

EDIT: Changed das golang Beispiel MarshalIndent für

Lesbarkeit verwendet

Edit 2 Das Beispiel von Ainar-G funktioniert gut für die leer Eltern versteckt, aber es Bestücken macht es viel schwieriger. "panic: runtime error: invalid memory address or nil pointer dereference"

Antwort

11

Example1 funktioniert nicht, da der ,omitempty Tag offenbar nur auf dem Element selbst funktioniert und nicht die a>b>c umschließenden Elemente.

Example2 funktioniert nicht, weil ,omitempty leere Strukturen nicht als leer erkennt. 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.

Keine Erwähnung von structs. Sie können die baz Beispiel Arbeit machen, indem Group1 auf einen Zeiger auf eine Struktur zu ändern:

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

Dann, wenn Sie Group1 füllen wollen, werden Sie es separat zuweisen müssen:

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

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

+0

Können Sie erklären, warum es mit einem Zeiger funktioniert? In den Dokumenten findet sich dazu kein Hinweis. – DonSeba

+0

Wenn ich jetzt versuche, die Struktur zu füllen, bekomme ich folgendes: 'panic: Laufzeitfehler: ungültige Speicheradresse oder Null-Zeigerdereferenzierung 'irgendeine Abhilfe dafür? – DonSeba

+0

@DonSeba Ich habe [die Verbindung] (http://golang.org/pkg/encoding/xml/#Marshal) in meiner Antwort gegeben. ', omitemperty' funktioniert für alles außer Strukturen. Ich kenne den genauen Grund nicht, ich denke, es hat etwas mit den Einschränkungen der Reflexion in Go zu tun. –