带有golang属性的xml文档

时间:2016-12-14 13:38:45

标签: xml go struct slice

我有一个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(整数),0和k2(bool),false

如何使用&#34; encoding / xml&#34; ?

1 个答案:

答案 0 :(得分:2)

您必须使用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,并且它具有A.I.I=1值,该值来自XML。

Venue.As切片的第二个元素有A.N=k2,并且它具有A.B.V=false值,取自XML。

如果它困扰你那么&#34;包装&#34; A struct包含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>