本文介绍了在Golang中解组XML数组:只获取第一个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码:

  type HostSystemIdentificationInfo [] struct {
IdentiferValue string`xml:identifierValue`
IdentiferType struct {
标签字符串`xml:标签``
汇总字符串`xml:摘要``
关键字字符串`xml:键
xml:identifierType`
}

func vsphereHost(v * vsphere.Vsphere,md * opentsdb.MultiDataPoint)错误{
res,err:= v.Info( HostSystem,[] string {
name,
summary.hardware.cpuMhz,
summary.hardware.memorySize,// bytes
summary.hardware .nu​​mCpuCores,
summary.hardware.numCpuCores,
summary.quickStats.overallCpuUsage,// MHz
summary.quickStats.overallMemoryUsage,// MB
summary.hardware.otherIdentifyingInfo,
summary.hardware.model,
})
for _,r:=范围res {
for _,p:= range r.Props {
如果pN ame ==summary.hardware.otherIdentifyingInfo{
var t HostSystemIdentificationInfo
fmt.Println(p.Val.Inner)
err:= xml.Unmarshal([] byte(p.Val .Inner),& t)
if err!= nil {
return err
}
fmt.Println(t)
}
}

输出:

 < HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>< identifierValue> < / identifier><标识符类型><标签><标签><标签>< / key>< / identifierType>< / HostSystemIdentificationInfo>< / label>< summary>系统的资产标签< / summary>< key> ;< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>< identifierValue> Dell System< / identifierValue>< identifierType>< label> OEM特定字符串< / label>< summary> OEM特定字符串< / summary><< ; key> OemSpecificString< / key>< / identifierType>< / HostSystemIdentificationInfo>< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>< identifierValue>< / identifierValue>< identifierType>< label> ; OEM特定字符串< / label>< summary> OEM特定字符串< / summary>< key> OemSpecificString< / key>< / identifierType>< / HostSystemIdentificationInfo>< HostSystemIdentificationInfo xsi:type =HostSystemIdentificatio <标识符>< /标识符值>编辑< /标识符><标识符类型><标签>服务标签< / label><摘要>系统的服务标签< / summary>< key> ServiceTag< / key>< ; / identifierType>< / HostSystemIdentificationInfo> 
[{unknown {系统Asset Tag的资产标签资产标签}}]
< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>< identifierValue> < / identifier><标识符类型><标签><标签><标签>< / key>< / identifierType>< / HostSystemIdentificationInfo>< / label>< summary>系统的资产标签< / summary>< key> ;< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>< identifierValue> Dell System< / identifierValue>< identifierType>< label> OEM特定字符串< / label>< summary> OEM特定字符串< / summary><< ; key> OemSpecificString< / key>< / identifierType>< / HostSystemIdentificationInfo>< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>< identifierValue>< / identifierValue>< identifierType>< label> ; OEM特定字符串< / label>< summary> OEM特定字符串< / summary>< key> OemSpecificString< / key>< / identifierType>< / HostSystemIdentificationInfo>< HostSystemIdentificationInfo xsi:type =HostSystemIdentificatio < identifier> REDCATED< / identifierValue>< identifierType>< label>< />< / label>< ; / identifierType>< / HostSystemIdentificationInfo>
[{unknown {系统资产标签的资产标签资产标签}}]

问题是当我解组时,我只得到结果中的一个HostSystemIdentification结构而不是整个数组。如何解决这个问题?



这是一个减少问题的游乐场:

解决方案

在字符串中有多个顶级实体,您必须多次创建一个xml.Decoder并调用其Decode方法。请参阅

  package main 

import(
bytes
encoding / xml
fmt
io
log


类型HostSystemIdentificationInfo [] struct {
IdentiferValue string`xml:identifierValue`
IdentiferType struct {
标签字符串`xml:标签``
汇总字符串`xml:摘要``
关键字字符串`xml:键
xml:identifierType`
}

func main(){
d:= xml.NewDecoder(bytes.NewBufferString(VV))
for {
var t HostSystemIdentificationInfo
err:= d.Decode(& t)
if err == io.EOF {
break
}
if err!= nil {
log.Fatal(err)
}
fmt.Println(t)
}
}

const VV =`< HostSystemIdentificationInfo xsi :类型= HostSystemIdentificationInfo >
< identifierValue>未知< / identifierValue>
< identifierType>
< label>资产标签< / label>
< summary>系统的资产标签< / summary>
< key> AssetTag< / key>
< / identifierType>
< / HostSystemIdentificationInfo>
< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>
< identifierValue>戴尔系统< / identifierValue>
< identifierType>
< label> OEM特定字符串< / label>
<摘要> OEM特定字符串< / summary>
< key> OemSpecificString< / key>
< / identifierType>
< / HostSystemIdentificationInfo>
< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>
< identifierValue> 5 [0000]< / identifierValue>
< identifierType>
< label> OEM特定字符串< / label>
<摘要> OEM特定字符串< / summary>
< key> OemSpecificString< / key>
< / identifierType>
< / HostSystemIdentificationInfo>
< HostSystemIdentificationInfo xsi:type =HostSystemIdentificationInfo>
< identifierValue>删除< / identifierValue>
< identifierType>
< label>服务标签< / label>
< summary>系统的服务标签< / summary>
< key> ServiceTag< / key>
< / identifierType>
< / HostSystemIdentificationInfo>`


Code:

type HostSystemIdentificationInfo []struct {
    IdentiferValue string `xml:"identifierValue"`
    IdentiferType  struct {
        Label   string `xml:"label"`
        Summary string `xml:"summary"`
        Key     string `xml:"key"`
    } `xml:"identifierType"`
}

func vsphereHost(v *vsphere.Vsphere, md *opentsdb.MultiDataPoint) error {
    res, err := v.Info("HostSystem", []string{
        "name",
        "summary.hardware.cpuMhz",
        "summary.hardware.memorySize", // bytes
        "summary.hardware.numCpuCores",
        "summary.hardware.numCpuCores",
        "summary.quickStats.overallCpuUsage",    // MHz
        "summary.quickStats.overallMemoryUsage", // MB
        "summary.hardware.otherIdentifyingInfo",
        "summary.hardware.model",
    })
    for _, r := range res {
        for _, p := range r.Props {
            if p.Name == "summary.hardware.otherIdentifyingInfo" {
                var t HostSystemIdentificationInfo
                fmt.Println(p.Val.Inner)
                err := xml.Unmarshal([]byte(p.Val.Inner), &t)
                if err != nil {
                    return err
                }
                fmt.Println(t)
            }
        }
    }

Output:

<HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue> unknown</identifierValue><identifierType><label>Asset Tag</label><summary>Asset tag of the system</summary><key>AssetTag</key></identifierType></HostSystemIdentificationInfo><HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue>Dell System</identifierValue><identifierType><label>OEM specific string</label><summary>OEM specific string</summary><key>OemSpecificString</key></identifierType></HostSystemIdentificationInfo><HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue>5[0000]</identifierValue><identifierType><label>OEM specific string</label><summary>OEM specific string</summary><key>OemSpecificString</key></identifierType></HostSystemIdentificationInfo><HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue>REDACTED</identifierValue><identifierType><label>Service tag</label><summary>Service tag of the system</summary><key>ServiceTag</key></identifierType></HostSystemIdentificationInfo>
[{ unknown {Asset Tag Asset tag of the system AssetTag}}]
<HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue> unknown</identifierValue><identifierType><label>Asset Tag</label><summary>Asset tag of the system</summary><key>AssetTag</key></identifierType></HostSystemIdentificationInfo><HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue>Dell System</identifierValue><identifierType><label>OEM specific string</label><summary>OEM specific string</summary><key>OemSpecificString</key></identifierType></HostSystemIdentificationInfo><HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue>5[0000]</identifierValue><identifierType><label>OEM specific string</label><summary>OEM specific string</summary><key>OemSpecificString</key></identifierType></HostSystemIdentificationInfo><HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo"><identifierValue>REDCATED</identifierValue><identifierType><label>Service tag</label><summary>Service tag of the system</summary><key>ServiceTag</key></identifierType></HostSystemIdentificationInfo>
[{ unknown {Asset Tag Asset tag of the system AssetTag}}]

So the problem is when I unmarshal I'm only getting one of the HostSystemIdentification structs in the result instead of the full array. How do I fix this?

Here is a go playground with the problem reduced: http://play.golang.org/p/5uRJ6Eu8jK

解决方案

Since you have multiple top-level entities in the string, you must create a xml.Decoder and call its Decode method many times. See http://play.golang.org/p/_1a77YGLoX

package main

import (
    "bytes"
    "encoding/xml"
    "fmt"
    "io"
    "log"
)

type HostSystemIdentificationInfo []struct {
    IdentiferValue string `xml:"identifierValue"`
    IdentiferType  struct {
        Label   string `xml:"label"`
        Summary string `xml:"summary"`
        Key     string `xml:"key"`
    } `xml:"identifierType"`
}

func main() {
    d := xml.NewDecoder(bytes.NewBufferString(VV))
    for {
        var t HostSystemIdentificationInfo
        err := d.Decode(&t)
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(t)
    }
}

const VV = `<HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo">
  <identifierValue> unknown</identifierValue>
  <identifierType>
    <label>Asset Tag</label>
    <summary>Asset tag of the system</summary>
    <key>AssetTag</key>
  </identifierType>
</HostSystemIdentificationInfo>
<HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo">
  <identifierValue>Dell System</identifierValue>
  <identifierType>
    <label>OEM specific string</label>
    <summary>OEM specific string</summary>
    <key>OemSpecificString</key>
  </identifierType>
</HostSystemIdentificationInfo>
<HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo">
  <identifierValue>5[0000]</identifierValue>
  <identifierType>
    <label>OEM specific string</label>
    <summary>OEM specific string</summary>
    <key>OemSpecificString</key>
  </identifierType>
</HostSystemIdentificationInfo>
<HostSystemIdentificationInfo xsi:type="HostSystemIdentificationInfo">
  <identifierValue>REDACTED</identifierValue>
  <identifierType>
    <label>Service tag</label>
    <summary>Service tag of the system</summary>
    <key>ServiceTag</key>
  </identifierType>
</HostSystemIdentificationInfo>`

这篇关于在Golang中解组XML数组:只获取第一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 17:58