使用Go解析XML,有多个项目

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

Parsing xml with Go, having multiple items

问题

我只能翻译代码部分,以下是翻译好的代码:

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"encoding/xml"
)

type RSS struct {
	XMLName xml.Name `xml:"rss"`
	items   Items    `xml:"channel"`
}

type Items struct {
	XMLName   xml.Name `xml:"channel"`
	ItemList  []Item   `xml:"item"`
}

type Item struct {
	Title       string `xml:"title"`
	Link        string `xml:"link"`
	Description string `xml:"description"`
}

func main() {
	res, err := http.Get("http://news.google.com/news?hl=en&gl=us&q=samsung&um=1&ie=UTF-8&output=rss")
	if err != nil {
		log.Fatal(err)
	}
	asText, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	var i RSS
	err = xml.Unmarshal([]byte(asText), &i)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%#v", i)

	for c, item := range i.items.ItemList {
		fmt.Printf("\t%d: %s\n", c, item.Title)
	}

	res.Body.Close()
}

输出结果如下:

main.RSS{XMLName:xml.Name{Space:"", Local:"rss"}, items:main.Items{XMLName:xml.Name{Space:"", Local:""}, ItemList:[]main.Item(nil)}}
英文:

I just can't get this simple thing to work. I'm just trying to parse a simple RSS XML and put all the items in an array of structs.

this is my code:

package main 

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"encoding/xml"
)

type RSS struct {
	XMLName xml.Name `xml:"rss"`
	items Items `xml:"channel"`
}
type Items struct {
	XMLName xml.Name `xml:"channel"`
	ItemList []Item `xml:"item"`
}
type Item struct {
	title string `xml:"title"`
	link string
	description string
}

func main() {
	res, err := http.Get("http://news.google.com/news?hl=en&gl=us&q=samsung&um=1&ie=UTF-8&output=rss")
	if err != nil {
		log.Fatal(err)
	}
	asText, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	
	var i RSS
	err = xml.Unmarshal([]byte(asText), &i)
	if err != nil {
        log.Fatal(err)  
    }
	
//	fmt.Printf("\ttxt2: %s\n", asText)
	fmt.Printf("%#v", i)
	
	for c, item := range i.items.ItemList {
		fmt.Printf("\t%d: %s\n", c, item.title)
	}
	
	res.Body.Close()
	
}

this is the output of dumping i:

main.RSS{XMLName:xml.Name{Space:"", Local:"rss"}, items:main.Items{XMLName:xml.Name{Space:"", Local:""}, ItemList:[]main.Item(nil)}}

答案1

得分: 9

Unmarshal的文档中:

因为Unmarshal使用reflect包,它只能赋值给导出的(大写)字段。Unmarshal使用区分大小写的比较将XML元素名称与标签值和结构字段名称进行匹配。

所以你需要将结构字段名称改为大写。不幸的是,这样它们就不再与XML元素名称匹配,所以你需要重复它们的小写版本。

这是一个使用你的RSS feed的前两个项目的工作示例:https://go.dev/play/p/IJpEC2qpUWo

英文:

From the docs of Unmarshal:

> Because Unmarshal uses the reflect package, it can only assign to exported (upper case) fields. Unmarshal uses a case-sensitive comparison to match XML element names to tag values and struct field names.

So you need to upper-case your struct field names. Unfortunately, then they don't match the XML element names anymore, so you'll have to repeat their lower-case versions.

Here's a working example with the first two items of your RSS feed: https://go.dev/play/p/IJpEC2qpUWo

huangapple
  • 本文由 发表于 2013年2月13日 22:34:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/14855892.html
匿名

发表评论

匿名网友

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

确定