go RSS 数据源

代码清单 2-49 matchers/rss.go:第 14 行到第 58 行
14 type (
15 // item根据item字段的标签,将定义的字段
16 // 与rss文档的字段关联起来
17 item struct {
18 XMLName xml.Name xml:"item"
19 PubDate string xml:"pubDate"
20 Title string xml:"title"
21 Description string xml:"description"
22 Link string xml:"link"
23 GUID string xml:"guid"
24 GeoRssPoint string xml:"georss:point"
25 }
26
27 // image根据image字段的标签,将定义的字段
28 // 与rss文档的字段关联起来
29 image struct {
30 XMLName xml.Name xml:"image" 31 URL string xml:"url"
32 Title string xml:"title"
33 Link string xml:"link"
34 }
35
36 // channel根据channel字段的标签,将定义的字段
37 // 与rss文档的字段关联起来
38 channel struct {
39 XMLName xml.Name xml:"channel"
40 Title string xml:"title"
41 Description string xml:"description"
42 Link string xml:"link"
43 PubDate string xml:"pubDate"
44 LastBuildDate string xml:"lastBuildDate"
45 TTL string xml:"ttl"
46 Language string xml:"language"
47 ManagingEditor string xml:"managingEditor"
48 WebMaster string xml:"webMaster"
49 Image image xml:"image"
50 Item []item xml:"item"
51 }
52
53 // rssDocument定义了与rss文档关联的字段 54 rssDocument struct {
55 XMLName xml.Name xml:"rss"
56 Channel channel xml:"channel"
57 }
58 )
如果把这些结构与任意一个数据源的 RSS 文档对比,就能发现它们的对应关系。解码 XML 的方法与我们在 feed.go 代码文件里解码 JSON 文档一样。接下来我们可以看看rssMatcher类型的声明,如代码清单 2-50 所示。
代码清单 2-50 matchers/rss.go:第 60 行到第 61 行
60 // rssMatcher 实现了Matcher接口
61 type rssMatcher struct{}
再说明一次,这个声明与defaultMatcher类型的声明很像。因为不需要维护任何状态,
所以我们使用了一个空结构来实现Matcher接口。接下来看看匹配器init函数的实现,如代码清单 2-51 所示。
代码清单 2-51 matchers/rss.go:第 63 行到第 67 行
63 // init 将匹配器注册到程序里
64 func init() {
65 var matcher rssMatcher
66 search.Register(“rss”, matcher)
67 }
就像在默认匹配器里看到的一样,init函数将rssMatcher类型的值注册到程序里,以备
后用。让我们再看一次 main.go 代码文件里的导入部分,如代码清单 2-52 所示。
代码清单 2-52 main.go:第 07 行到第 08 行
07 _ “github.com/goinaction/code/chapter2/sample/matchers”
08 “github.com/goinaction/code/chapter2/sample/search”
main.go 代码文件里的代码并没有直接使用任何matchers包里的标识符。不过,我们依旧需要编译器安排调用 rss.go 代码文件里的init函数。在第 07 行,我们使用下划线标识符作为别名导入 matchers 包,完成了这个调用。这种方法可以让编译器在导入未被引用的包时不报错,而且依旧会定位到包内的init函数。我们已经看过了所有的导入、类型和初始化函数,现在来看看最后两个用于实现Matcher接口的方法,如代码清单 2-53 所示。
代码清单 2-53 matchers/rss.go:第 114 行到第 140 行
114 // retrieve发送HTTP Get请求获取rss数据源并解码
115 func (m rssMatcher) retrieve(feed *search.Feed) (*rssDocument, error) {
116 if feed.URI == “” {
117 return nil, errors.New(“No rss feed URI provided”)
118 }
119
120 // 从网络获得rss数据源文档
121 resp, err := http.Get(feed.URI)
122 if err != nil {
123 return nil, err
124 }
125
126 // 一旦从函数返回,关闭返回的响应链接
127 defer resp.Body.Close() 128
129 // 检查状态码是不是200,这样就能知道
130 // 是不是收到了正确的响应
131 if resp.StatusCode != 200 {
132 return nil, fmt.Errorf(“HTTP Response Error %d\n”, resp.StatusCode)
133 }
134
135 // 将rss数据源文档解码到我们定义的结构类型里
136 // 不需要检查错误,调用者会做这件事
137 var document rssDocument
138 err = xml.NewDecoder(resp.Body).Decode(&document)
139 return &document, err
140 }
方法retrieve并没有对外暴露,其执行的逻辑是从 RSS 数据源的链接拉取 RSS 文档。在第 121 行,可以看到调用了http包的Get方法。我们会在第 8 章进一步介绍这个包,现在只需要知道,使用http包,Go 语言可以很容易地进行网络请求。当Get方法返回后,我们可以得到一个指向Response类型值的指针。之后会监测网络请求是否出错,并在第 127 行安排函数返回时调用Close方法。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值