在Go中解组异构的XML元素列表

时间:2016-12-06 04:44:54

标签: xml go

我有一个这样的XML文档:

<val>
<alpha β='γ'/>
<α δ='ε'/>
(a whole bunch of the above, in random order)
</val>

换句话说,一个异构列表。我想使用Go encoding/xml包解组它。我怎么能这样做?

1 个答案:

答案 0 :(得分:2)

您无法在Go中对此类XML文档进行建模,也无法解组为interace{},因此我建议事件驱动解析。

这种事件驱动的解析意味着当您解析XML文档的(令牌)时,您会收到“遇到的元素”或“遇到的元素”(当然包含元素的详细信息)等事件,以及这些事件控制程序的流程(分支和/或根据它们改变内部状态)。

以下示例将向您展示此原理。它不处理更复杂的XML,因为我希望该示例简短,但这种技术可用于解析任何XML文档。

使用xml.Decoder创建xml.NewDecoder(),并通过重复调用Decoder.Token()来解析XML的内容(循环播放)。

<val>内的元素将收集在[]Entry类型的切片中:

type Entry struct {
    Name  string
    Attr  string
    Value string
}

func main() {
    decoder := xml.NewDecoder(strings.NewReader(src))

    entries := []Entry{}
    for {
        t, err := decoder.Token()
        if err != nil {
            if err != io.EOF {
                fmt.Println(err)
            }
            break
        }
        if se, ok := t.(xml.StartElement); ok && len(se.Attr) > 0 {
            entries = append(entries, Entry{
                Name:  se.Name.Local,
                Attr:  se.Attr[0].Name.Local,
                Value: se.Attr[0].Value,
            })
        }
    }

    fmt.Printf("%+v\n", entries)
}

const src = `<val>
<alpha β='γ'/>
<α δ='ε'/>
<x y='z'/>
</val>`

输出(在Go Playground上尝试):

[{Name:alpha Attr:β Value:γ} {Name:α Attr:δ Value:ε} {Name:x Attr:y Value:z}]