go 的 `encoding/xml` 包支持通过 `xml:",any"` 标签捕获任意子元素,并结合 `xmlname` 字段保留元素名与原始顺序,从而精确还原混合、无序、可变的 xml 序列结构。
当 XML 文档中存在
正确做法是:将所有子元素统一视为同一类型,利用 xml:",any" 动态捕获,再通过 XMLName 字段识别具体元素类型。示例如下:
package main
import (
"encoding/xml"
"fmt"
)
type RootNode struct {
Elements []Element `xml:",any"`
}
type Element struct {
XMLName xml.Name
// 可选:嵌入具体类型的字段,或按需解析内容
A *ElementA `xml:"ElementA"`
B *ElementB `xml:"ElementB"`
C *ElementC `xml:"ElementC"`
}
type ElementA struct {
Content string `xml:",chardata"`
}
type ElementB struct {
ID string `xml:"id,attr"`
}
type ElementC struct {
Value int `xml:"value,attr"`
}
func main() {
data := `
hello
world
`
var root RootNode
if err := xml.Unmarshal([]byte(data), &root); err != nil {
pa
nic(err)
}
for i, e := range root.Elements {
switch e.XMLName.Local {
case "ElementA":
fmt.Printf("[%d] ElementA: %q\n", i, e.A.Content)
case "ElementB":
fmt.Printf("[%d] ElementB: id=%q\n", i, e.B.ID)
case "ElementC":
fmt.Printf("[%d] ElementC: value=%d\n", i, e.C.Value)
default:
fmt.Printf("[%d] Unknown: %s\n", i, e.XMLName.Local)
}
}
}✅ 关键要点:
⚠️ 注意事项:
综上,xml:",any" + XMLName 是 Go 中处理 XSD 中