xml 具有 golang 属性的文档

xml document with attributes with golang

我有一个 XML 文档,看起来像这样

<?xml version="1.0"?>
<!DOCTYPE venue SYSTEM "z.dtd">
<venue>
<c>
    <a n="k1"><i>0</i></a>
    <a n="k2"><b v="f"/></a>
</c>
</venue>

我想提取 k1 (integer) , 0 和 k2 (bool) , false

如何使用 "encoding/xml" 执行此操作?

您必须使用 Go 结构为您的 XML 结构建模。

对于可能具有不同内容的元素(子元素),一种选择是列出所有可能的变化,并且只会解组遇到的元素。

您的 XML 结构可以这样建模:

type Venue struct {
    As []A `xml:"c>a"`
}

type A struct {
    N string `xml:"n,attr"`
    I I      `xml:"i"`
    B B      `xml:"b"`
}

type I struct {
    I int `xml:",chardata"`
}

type B struct {
    V bool `xml:"v,attr"`
}

以及解组 XML 文档的代码:

func main() {
    var v Venue
    err := xml.Unmarshal([]byte(data), &v)
    fmt.Printf("%+v %v", v, err)
}

const data = `<?xml version="1.0"?>
<!DOCTYPE venue SYSTEM "z.dtd">
<venue>
<c>
    <a n="k1"><i>1</i></a>
    <a n="k2"><b v="f"/></a>
</c>
</venue>`

输出(在 Go Playground 上尝试):

{As:[{N:k1 I:{I:1} B:{V:false}} {N:k2 I:{I:0} B:{V:false}}]} <nil>

如您所见,Venue.As 切片的第一个元素有 A.N=k1,它有取自 XML 的 A.I.I=1 值。

Venue.As 切片的第二个元素具有 A.N=k2,它具有取自 XML.

A.B.V=false

如果 "wrapper" A 结构包含 IB 字段(即使其中只有一个包含有效数据),这让您感到困扰,您可以将它们声明为指针,XML 中不存在的将是 nil(这样可以明显且容易地分辨 XML 中存在的元素):

type A struct {
    N string `xml:"n,attr"`
    I *I     `xml:"i"`
    B *B     `xml:"b"`
}

这次输出(在Go Playground上试试):

{As:[{N:k1 I:0x1050e24c B:<nil>} {N:k2 I:<nil> B:0x1050e2f5}]} <nil>