使用Go语言解析大型XML文件

huangapple go评论89阅读模式
英文:

Parsing huge XML file using Go

问题

我们需要使用Go语言解析一个巨大的XML文件。我们希望使用类似SAX的基于事件的算法,使用xml.NewDecoder()decoder.Token()库函数。我们已经创建了带有XML注释的适当的结构类型。到目前为止,一切都很简单。

现在,我们遍历文件并检测xml.StartElement标记。这里出现了问题。我们需要仅解码此起始标记的属性,并继续解析其内容。如果我们调用token.DecodeElement(),整个内容将在我们的场景中被“解码”或跳过。

如何仅解码特定StartElement的属性并继续解析元素的内容?

英文:

We need to parse a huge XML file using Go. We'd like to use a SAX-like event based algorithm using xml.NewDecoder() and decoder.Token() library calls. We've created the appropriate struct types with XML annotations. Everything easy peasy so far.

Now, we go through the file and detect the xml.StartElement tokens. And here comes the problem. We need to decode ONLY the attributes of this starting token and continue into its content. If we call token.DecodeElement() the whole content is "decoded" or skipped in our scenario.

How to decode only the attributes of a specific StartElement and continue to the element's body?

答案1

得分: 2

我在go-wikiparse中使用普通的结构/反射解码来解析维基百科的XML转储文件(约50GB的XML文件)。这非常简单。

基本策略如下:

首先,读取信封标记:

d := xml.NewDecoder(r)
_, err := d.Token()
if err != nil {
    return nil, err
}

例如,对于<someDocument><billions-of-other-things/></someDocument>,这将给你返回someDocument。

然后,你可以在循环中使用结构解码下一个元素:

var i item
d.Decode(&i)

占用的内存不多,而且解析起来非常简单。

英文:

I parse wikipedia xml dumps (~50GB xml files) in go-wikiparse using plain struct/reflect decoding. It's super simple.

The strategy is basically this:

First, read the envelope token:

d := xml.NewDecoder(r)
_, err := d.Token()
if err != nil {
    return nil, err
}

e.g., for <someDocument><billions-of-other-things/></someDocument> that will give you someDocument.

Then, you can just struct decode the next things in a loop:

var i item
d.Decode(&i)

Not much RAM, and it's super easy to parse.

huangapple
  • 本文由 发表于 2014年11月5日 19:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/26756382.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定