如何使用Golang解码Reddit的RSS? [英] How to decode Reddit's RSS using Golang?

查看:179
本文介绍了如何使用Golang解码Reddit的RSS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用Go的XML包,因此看不到以下代码有什么问题。

I've been playing about with Go's XML package and cannot see what is wrong with the following code.

package main

import (
    "encoding/xml"
    "fmt"
    "net/http"
) 

type Channel struct {
    Items Item
}

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

func main() {

    var items = new(Channel)
    res, err := http.Get("http://www.reddit.com/r/google.xml")

    if err != nil {
        fmt.Printf("Error: %v\n", err)
    } else {
        decoded := xml.NewDecoder(res.Body)

        err = decoded.Decode(items)

        if err != nil {
            fmt.Printf("Error: %v\n", err)
        }

        fmt.Printf("Title: %s\n", items.Items.Title)
    }
}

上面的代码运行无误,并打印到终端:

The above code runs without any errors and prints to the terminal:

Title:

该结构似乎是空的,但我看不到为什么它没有填充XML数据。

The struct seems empty but I can't see why it isn't getting populated with the XML data.

推荐答案

您的程序已接近完成,但需要指定更多上下文来匹配XML文档。

Your program comes close, but needs to specify just a little bit more context to match the XML document.

您需要修改字段标签,以帮助引导XML绑定通过
Channel 结构传递到 Item 结构:

You need to revise your field tags to help guide the XML binding down through your Channel structure to your Item structure:

type Channel struct {
    Items []Item `xml:"channel>item"`
}

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

每个 encoding / xml.Unmarshal() ,此处适用第七个项目符号:

Per the documentation for encoding/xml.Unmarshal(), the seventh bullet item applies here:


如果XML元素包含名称与$ b $相匹配的子元素b标记格式为 a或 a> b> c的前缀,解组
将XML结构查找具有给定名称
的元素,并将最里面的元素映射到该结构
字段。以>开头的标记等效于以字段名开头的
,后跟>。

If the XML element contains a sub-element whose name matches the prefix of a tag formatted as "a" or "a>b>c", unmarshal will descend into the XML structure looking for elements with the given names, and will map the innermost elements to that struct field. A tag starting with ">" is equivalent to one starting with the field name followed by ">".

您的情况下,您希望遍历顶级< rss> 元素的< channel> 元素查找每个< item> 元素。不过请注意,我们实际上不需要-指定 Channel 结构应遍历顶级 < rss> 元素,方法是将 Items 字段的标签写为

In your case, you're looking to descend through the top-level <rss> element's <channel> elements to find each <item> element. Note, though, that we don't need to—an in fact can't—specify that the Channel struct should burrow through the top-level <rss> element by writing the Items field's tag as

`xml:"rss>channel>item"`

该上下文是隐式的;提供给 Unmarshall()的结构已经映射到顶级XML元素。

That context is implicit; the struct supplied to Unmarshall() already maps to the top-level XML element.

请注意,您的 Channel 结构的 Items 字段应为slice_of- Item ,而不仅仅是单个 Item

Note too that your Channel struct's Items field should be of type slice-of-Item, not just a single Item.

您提到您很难使该建议生效。这是一个完整的清单,我发现它可以像人们期望的那样工作:

You mentioned that you're having trouble getting the proposal to work. Here's a complete listing that I find works as one would expect:

package main

import (
    "encoding/xml"
    "fmt"
    "net/http"
    "os"
) 

type Channel struct {
    Items []Item `xml:"channel>item"`
}

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

func main() {
    if res, err := http.Get("http://www.reddit.com/r/google.xml"); err != nil {
        fmt.Println("Error retrieving resource:", err)
        os.Exit(1)
    } else {
        channel := Channel{}
        if err := xml.NewDecoder(res.Body).Decode(&channel); err != nil {
            fmt.Println("Error:", err)
            os.Exit(1)
        } else if len(channel.Items) != 0 {
            item := channel.Items[0]
            fmt.Println("First title:", item.Title)
            fmt.Println("First link:", item.Link)
            fmt.Println("First description:", item.Description)
        }
    }
}

这篇关于如何使用Golang解码Reddit的RSS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆