

新闻资讯
技术学院go 的 `xml.unmarshal` 要求输入 xml 有且仅有一个根元素;若原始数据是多个并列的 `
在 Go 中处理 VMware vSphere 等系统返回的 XML 数据时,一个常见陷阱是:summary.hardware.otherIdentifyingInfo 字段的值并非标准 XML 文档(即带单一根节点),而是多个同级
✅ 正确解法是使用 xml.Decoder,它支持流式解析,可多次调用 Decode() 方法,每次读取并解析一个独立的 XML 元素:
import (
"bytes"
"encoding/xml"
"io"
)
type HostSystemIdentificationInfo struct { // 注意:此处改为普通 struct,非切片
IdentifierValue string `xml:"identifierValue"`
IdentifierType struct {
Label string `xml:"label"`
Summary string `xml:"summary"`
Key string `xml:"key"`
} `xml:"identifierType"`
}
// 解析多个并列的 HostSystemIdentificationInfo
func parseIdentificationInfos(xmlData string) ([]HostSystemIdentificationInfo, error) {
var results []HostSystemIdentificationInfo
decoder := xml.NewDecoder(bytes.NewBufferString(xmlData))
for {
var item HostSystemIdentificationInfo
err := decoder.Decode(&item)
if err == io.EOF {
break // 所有元素已读完
}
if err != nil {
return nil, fmt.Errorf("failed to decode XML item: %w", err)
}
results = append(results, item)
}
return results, nil
}? 关键要点:
在你的 vSphere 客户端逻辑中,只需将原 xml.Unmarshal 替换为上述 parseIdentificationInfos 调用:
if p.Name == "summary.hardware.otherIdentifyingInfo" {
infos, err := parseIdentificationInfos(p.Val.Inner)
if err != nil {
return fmt.Errorf("failed to parse host identification info: %w", err)
}
fmt.Printf("Parsed %d identification entries\n", len(infos))
for _, info := range infos {
fmt.Printf("- Value: %q, Type: %q (Key: %q)\n",
info.IdentifierValue,
info.IdentifierType.Label,
info.IdentifierType.Key)
}
}✅ 总结:当面对“无根多节点 XML 字符串”时,xml.Decoder + 循环 Decode() 是 Go 标准库提供的标准、可靠且内存友好的解决方案。避免强行添加虚拟根节点(如