2014-04-17 8 views
10

Ich kann nicht scheinen, um herauszufinden, warum dies nicht funktioniertGolang XML-Attribut und Wert

type HostProperties struct {                              
      XMLName xml.Name `xml:HostProperties"`                         
      Info []InfoList `xml:"tag"`                           
}                                     
    type InfoList struct {                               
      HostEnd   string `xml:",chardata"`                         
      PatchSummary string `xml:",chardata"`                         
      CPE1   string `xml:",chardata"`                         
      CPE0   string `xml:",chardata"`                         
      SystemType  string `xml:",chardata"`                         
      OperatingSystem string `xml:",chardata"`                         
      MacAddress  string `xml:",chardata"`                         
      Traceroute  string `xml:",chardata"`                         
      IP    string `xml:",chardata"`                         
      FQDN   string `xml:",chardata"`                         
      HostStart  string `xml:",chardata"`                         
    } 
<HostProperties> 
<tag name="HOST_END">Thu Feb 20 12:38:24 2014</tag> 
<tag name="patch-summary-total-cves">4</tag> 
<tag name="cpe-1">cpe:/a:openbsd:openssh:5.6 -&gt; OpenBSD OpenSSH 5.6</tag> 
<tag name="cpe-0">cpe:/o:vmware:esx_server</tag> 
<tag name="system-type">hypervisor</tag> 
<tag name="operating-system">VMware ESXi</tag> 
<tag name="mac-address">00:00:00:00:00:00</tag> 
<tag name="traceroute-hop-0">172.28.28.29</tag> 
<tag name="host-ip">172.28.28.29</tag> 
<tag name="host-fqdn">foobar.com</tag> 
<tag name="HOST_START">Thu Feb 20 12:30:14 2014</tag> 
</HostProperties> 

Ergebnisse

{HostEnd:172.28.28.29 PatchSummary: CPE1: CPE0: SystemType: OperatingSystem: MacAddress: Traceroute: IP: FQDN: HostStart:} 

Es schafft eine Reihe von neuen Scheiben nur mit dem ersten Element ausgefüllt und selbst dann ist es das falsche Element. Es füllt die anderen Variablen nicht aus. Der Rest der Datei scheint gut zu parsen, kann einfach diesen Teil nicht herausfinden.

Antwort

17

Ich glaube nicht, dass Sie das XML-Parsing so machen können. Hier ist das Beste, was ich tun konnte, (run it on the playground)

var data = `<HostProperties> 
<tag name="HOST_END">Thu Feb 20 12:38:24 2014</tag> 
<tag name="patch-summary-total-cves">4</tag> 
<tag name="cpe-1">cpe:/a:openbsd:openssh:5.6 -&gt; OpenBSD OpenSSH 5.6</tag> 
<tag name="cpe-0">cpe:/o:vmware:esx_server</tag> 
<tag name="system-type">hypervisor</tag> 
<tag name="operating-system">VMware ESXi</tag> 
<tag name="mac-address">00:00:00:00:00:00</tag> 
<tag name="traceroute-hop-0">172.28.28.29</tag> 
<tag name="host-ip">172.28.28.29</tag> 
<tag name="host-fqdn">foobar.com</tag> 
<tag name="HOST_START">Thu Feb 20 12:30:14 2014</tag> 
</HostProperties>` 

type HostProperties struct { 
    XMLName xml.Name `xml:HostProperties"` 
    Tags []Tag `xml:"tag"` 
} 

type Tag struct { 
    Key string `xml:"name,attr"` 
    Value string `xml:",chardata"` 
} 

func main() { 
    v := new(HostProperties) 
    err := xml.Unmarshal([]byte(data), v) 
    if err != nil { 
     fmt.Printf("error: %v", err) 
     return 
    } 
    fmt.Printf("v = %#v\n", v) 

} 

Wenn Sie wirklich wollen, dass InfoList Struktur werden Sie durch die Tags laufen müssen und füllen es in. Ich würde wahrscheinlich halten es nur in eine map[string]string obwohl wie diese

tags := make(map[string]string) 
for _, tag := range v.Tags { 
    tags[tag.Key] = tag.Value 
} 
fmt.Printf("map = %#v\n", tags) 
+0

Sieht aus wie es ist fast da, aber es setzt jeden Wert auf seine eigene Linie. Ich mag die Idee der map [string] string. Wie würde ich darüber gehen? Oder wo könnte ich hinschauen? Wirklich neu zu gehen. '{Key: HOST_END Wert: Do Feb 20 12:38:24 2014}' '{Key: patch-summary-total-cves Wert: 4}' – b00stfr3ak

+0

Ich habe ein wenig hinzugefügt, wie man die Daten in eine Karte einfügt [Spielplatz] (http://play.golang.org/p/nAeoGIbB7R) –

+0

Danke, das hat funktioniert. Ich muss jedoch überdenken, wie ich die ganze Datei machen werde. Möglicherweise müssen Sie die Datei streamen, um die Daten in übereinstimmenden Blöcken zu erhalten. – b00stfr3ak

3

Das Tag xml:",chardata" wählt die Zeichendaten des aktuellen Elements wie gewünscht aus, jedoch nur für das erste Feld mit diesem Tag. Deshalb haben Sie die Ergebnisse erhalten, die Sie beobachtet haben.

Für die XML gegeben, würde ich Decodierung in die folgenden Typen vorschlagen:

type HostProperties struct { 
    XMLName xml.Name `xml:"HostProperties"` 
    Info []Tag `xml:"tag"` 
} 

type Tag struct { 
    Name string `xml:"name,attr"` 
    Value string `xml:",chardata"` 
} 

Es wird nicht geteilt automatisch die verschiedenen Namen-Tags in separate Felder für Sie aber: Sie müssen, dass nach der Verarbeitung tun das XML.

Verwandte Themen