Golang XML 属性和值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23126133/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Golang XML attribute and value
提问by b00stfr3ak
I can't seem to figure out why this isn't working
我似乎无法弄清楚为什么这不起作用
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 -> 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>
Results
结果
{HostEnd:172.28.28.29 PatchSummary: CPE1: CPE0: SystemType: OperatingSystem: MacAddress: Traceroute: IP: FQDN: HostStart:}
It creates a bunch of new slices with only the first element filled in and even then it's the wrong element. It's not filling out the other variables. The rest of the file seems to parse fine, just can't figure out this part.
它创建了一堆新切片,只填充了第一个元素,即使这样它也是错误的元素。它没有填写其他变量。文件的其余部分似乎解析得很好,只是无法弄清楚这部分。
回答by Nick Craig-Wood
I don't think you can make the XML parsing work like that. Here is the best I could come up with (run it on the playground)
我不认为你可以让 XML 解析像那样工作。这是我能想到的最好的(在操场上运行)
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 -> 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)
}
If you really want that InfoListstructure you'll have to run through the Tagsand fill it in. I'd probably just stick it in a map[string]stringthough like this
如果你真的想要那个InfoList结构,你必须遍历Tags并填写它。我可能会map[string]string像这样坚持下去
tags := make(map[string]string)
for _, tag := range v.Tags {
tags[tag.Key] = tag.Value
}
fmt.Printf("map = %#v\n", tags)
回答by James Henstridge
The tag xml:",chardata"will select the current element's character data, as you want, but only for the first field with that tag. This is why you got the results you observed.
该标签xml:",chardata"将根据需要选择当前元素的字符数据,但仅限于带有该标签的第一个字段。这就是为什么你得到你观察到的结果。
For the given XML, I would suggest decoding into the following types:
对于给定的 XML,我建议解码为以下类型:
type HostProperties struct {
XMLName xml.Name `xml:"HostProperties"`
Info []Tag `xml:"tag"`
}
type Tag struct {
Name string `xml:"name,attr"`
Value string `xml:",chardata"`
}
It won't automatically split the various named tags into separate fields for you though: you will need to do that after processing the XML.
不过,它不会自动为您将各种命名标签拆分为单独的字段:您需要在处理 XML 后执行此操作。

