在Go语言中遍历XML

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

Iterating through xml in go

问题

给定一个类似以下的xml块:

<data>
  <entry>
    ... 几个嵌套元素
  </entry>
  <entry>
    ... 更多嵌套元素
  </entry>
</data>

我该如何迭代遍历文档中的每个<entry>元素,并将其放入一个结构体中,在移动到下一个条目之前对其执行一些操作?

我已经能够解析并从上述的XML块中将数据存储到结构体中,其中只存在一个<entry>元素。也就是说,我已经成功地将类似以下的内容存储到结构体中:

<entry>
  ... 几个嵌套元素
</entry>
英文:

Given a block of xml similar to the following:

<data>
  <entry>
    ... several nested elements
  </entry>
  <entry>
    ... more nested elements
  </entry>
</data>

How can I iterate over each <entry> element in the document and put it into a struct to perform some operations on it before moving to the next entry?

I'm already able to parse and store data into structs from a block of XML as above where only a single <entry> element exists. That is to say that I am successfully able to store something like this into a struct:

<entry>
  ... several nested elements
</entry>

答案1

得分: 10

解析一个xmml文件直到达到entry元素是一种方法:

xmlFile, err := os.Open(filename)
    if err != nil {
    log.Fatal(err)
}
defer xmlFile.Close()
decoder := xml.NewDecoder(xmlFile)
total := 0
for {
    token, _ := decoder.Token()
    if token == nil {
        break
    }
    switch startElement := token.(type) {
        case xml.StartElement:
        if startElement.Name.Local == "entry" {
            // 在每个entry下执行需要的操作
        }
    }
}
英文:

Parsing an xmml file until you get to the entry elements is one way:

xmlFile, err := os.Open(filename)
    if err != nil {
    log.Fatal(err)
}
defer xmlFile.Close()
decoder := xml.NewDecoder(xmlFile)
total := 0
for {
    token, _ := decoder.Token()
    if token == nil {
        break
    }
    switch startElement := token.(type) {
        case xml.StartElement:
        if startElement.Name.Local == "entry" {
            // do what you need to do for each entry below
        }
    }
}

答案2

得分: 7

这是我会做的,根据文档和示例在http://golang.org/pkg/encoding/xml/

package main

import (
    "encoding/xml"
    "log"
)

// 代表一个<data>元素
type Data struct {
    XMLName xml.Name `xml:"data"`
    Entry   []Entry  `xml:"entry"`
}

// 代表一个<entry>元素
type Entry struct {
    Name string `xml:"name"`
    Age  int    `xml:"age"`
}

// 测试数据
var testXML string = `
<data>
    <entry>
        <name>John Doe</name>
        <age>28</age>
    </entry>
    <entry>
        <name>Jane Doe</name>
        <age>29</age>
    </entry>
    <entry>
        <name>Bob Doe</name>
        <age>30</age>
    </entry>
    <entry>
        <name>Beth Doe</name>
        <age>31</age>
    </entry>
</data>
`

func main() {

    data := &Data{}

    err := xml.Unmarshal([]byte(testXML), data)
    if err != nil {
        log.Fatal(err)
    }

    for i := 0; i < len(data.Entry); i++ {
        log.Printf("%#v", data.Entry[i])
    }
}

输出是:

main.Entry{Name:"John Doe", Age:28}
main.Entry{Name:"Jane Doe", Age:29}
main.Entry{Name:"Bob Doe", Age:30}
main.Entry{Name:"Beth Doe", Age:31}
英文:

Here's how I'd do it, per the documentation and examples in http://golang.org/pkg/encoding/xml/

<!-- language: lang-go -->

package main

import (
	&quot;encoding/xml&quot;
	&quot;log&quot;
)

// Represents a &lt;data&gt; element
type Data struct {
	XMLName xml.Name `xml:&quot;data&quot;`
	Entry   []Entry  `xml:&quot;entry&quot;`
}

// Represents an &lt;entry&gt; element
type Entry struct {
	Name string `xml:&quot;name&quot;`
	Age  int    `xml:&quot;age&quot;`
}

// Test data
var testXML string = `
&lt;data&gt;
    &lt;entry&gt;
        &lt;name&gt;John Doe&lt;/name&gt;
        &lt;age&gt;28&lt;/age&gt;
    &lt;/entry&gt;
    &lt;entry&gt;
        &lt;name&gt;Jane Doe&lt;/name&gt;
        &lt;age&gt;29&lt;/age&gt;
    &lt;/entry&gt;
    &lt;entry&gt;
        &lt;name&gt;Bob Doe&lt;/name&gt;
        &lt;age&gt;30&lt;/age&gt;
    &lt;/entry&gt;
    &lt;entry&gt;
        &lt;name&gt;Beth Doe&lt;/name&gt;
        &lt;age&gt;31&lt;/age&gt;
    &lt;/entry&gt;
&lt;/data&gt;
`

func main() {

	data := &amp;Data{}

	err := xml.Unmarshal([]byte(testXML), data)
	if err != nil {
		log.Fatal(err)
	}

	for i := 0; i &lt; len(data.Entry); i++ {
		log.Printf(&quot;%#v&quot;, data.Entry[i])
	}
}

Output is:

main.Entry{Name:&quot;John Doe&quot;, Age:28}
main.Entry{Name:&quot;Jane Doe&quot;, Age:29}
main.Entry{Name:&quot;Bob Doe&quot;, Age:30}
main.Entry{Name:&quot;Beth Doe&quot;, Age:31}

答案3

得分: 0

只需确保正确处理EOF

for {
	// 从XML文档中以流的形式读取标记。
	t, err := decoder.Token()
	if t == nil {
		if err == nil {
			continue
		}
		if err == io.EOF {
			break
		}
		log.Fatal(err)
	}
	
	//...
}
英文:

Just make sure you handle EOF properly

for {
	// Read tokens from the XML document in a stream.
	t, err := decoder.Token()
	if t == nil {
		if err == nil {
			continue
		}
		if err == io.EOF {
			break
		}
		log.Fatal(err)
	}
	
	//...
}

huangapple
  • 本文由 发表于 2012年8月23日 10:41:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/12084042.html
匿名

发表评论

匿名网友

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

确定