分享

Coding4Fun: 一个简单的 RSS 源

 busfly 2007-01-09

Coding4Fun: 一个简单的 RSS 源

发布日期: 10/27/2005 | 更新日期: 10/27/2005

Peter Bernhardt
3Leaf Development

很多年以前,我得到一个经验:我不需要了解所有事情就能了解整个世界。当然,得出这个结论本身就是一种自大的行为。但是这种自大源于年轻无知,现在我更清楚地认识到了这一点。实际上,这个事实只有在 Internet 时代才被放大了,因为我发现我不可能跟上 Web 上永不停止的信息、思想和观念流。甚至在我感兴趣的领域,我也很难跟上 Visual Basic、Visual C# 和 .NET Framework 的最新发展。

因此,在接下来的几个课程中,我将探索通过不同的方法来使用您很可能已经熟悉的工具:RSS(即真正简单的联合发布系统)- 一种能够大大减轻信息超载现象的技术。

作为快速入门,Wikpedia 将 RSS 描述为:“对 Web 内容的间断介绍以及指向完整内容的链接。此信息以 XML 文件的形式提供,称为 RSS 源、webfeed、RSS 流或 RSS 通道。除了使联合更方便以外,RSS 还使经常访问网站的读者能够使用新信息联合器跟踪该网站的更新。” [有关完整的信息,请参阅 RSS on Wikpedia(英文)。]

在开始以前,让我们先来看一个可以使用 Visual Web Developer 2005 Express Edition 创建的简单 RSS 源阅读器。我将创建一个控件,从所需的站点中提取 RSS 源,并对该内容进行组织以显示在网页上。当然,如果您是为了自己使用而联合内容,也可以创建 Windows 应用程序形式的 RSS 源阅读器,或者利用任何一个已有的免费 RSS 客户端应用程序 [例如,RSS Reader(英文)或 SharpReader(英文)]。但是,在 Web 应用程序中联合内容有其他目的 - 它使您能够扩展自己创建的内容,并丰富了访问您站点的用户的体验。

在涉及代码之前,让我们先看一小段典型的 RSS 2.0 文件内容。在此示例中,联合的提供程序为 Microsoft 的 MSDN 网站,并且我使用了 Visual Basic 内容专用的 RSS 源。

<rss
xmlns:msdn="http://msdn.microsoft.com/aboutmsdn/rss/"
xmlns:dc="http:///dc/elements/1.1/"
xmlns:msdndomain="http://msdn.microsoft.com/aboutmsdn/rss/domains"
version="2.0">
<channel>
<title>MSDN: Visual Basic</title>
<link>http://msdn.microsoft.com/vbasic/</link>
<description>Recently Published Visual Basic Content</description>
<language>en-us</language>
<pubDate>Thu, 30 Jun 2005 13:01:02 GMT</pubDate>
<lastBuildDate>Thu, 30 Jun 2005 13:01:02 GMT</lastBuildDate>
<generator>MSDN RSS Service 1.1.0.0</generator>
<ttl>1440</ttl>
<item>
<title>June CTP of Visual Studio 2005 Available to MSDN Subscribers</title>
<description>The latest Community Technical Preview of Visual Studio 2005
is now available for download to MSDN subscribers.</description>
<link>http://msdn.microsoft.com/subscriptions/</link>
<category domain="msdndomain:ContentType">Announcement</category>
<category domain="msdndomain:Subject">.NET development</category>
<msdn:headlineImage>http://msdn.microsoft.comicons/article.gif</msdn:headlineImage>
<msdn:contentType>Announcement</msdn:contentType>
<msdn:simpleDate>Jun 27</msdn:simpleDate>
<guid isPermaLink="false">Titan_1106</guid>
<pubDate>Tue, 28 Jun 2005 02:00:13 GMT</pubDate>
</item>
<!-- more items follow -->
</channel>
</rss>

典型的源文件在下载时附带有相关信息,但其中部分信息并非所有联合提供程序都会包含(例如,MSDN 的标题图像就不是标准信息)。在 XML 结构的顶部是一个 <channel> 节点,该节点包含标题和说明,用来简单描述内容项的列表。该 <channel> 节点包含很多子 <item> 节点,用来表示每篇文章(包括文章的标题、说明、发布日期以及指向全文的链接)。

在 Visual Web Developer 2005 Express Edition 中创建新网站之后,我添加了一个“Web 用户控件”,用来显示此信息。


ASP.NET 2.0 的功能之一是它既支持 Visual Studio 2003 开发人员所熟悉的代码分离模型,也支持(相对比较新的)嵌入代码模型,后者允许在 .aspx 或 .ascx 文件的 <script> 标记内编写所有代码。尽管使用嵌入代码的执行方式与 ASP.NET 页的执行方式完全相同,我更喜欢代码分离模型,并且本示例通篇使用代码分离模型。另外,请您注意,我使用 Visual Basic 来编写此应用程序的代码。

在设计器中工作时,我向控件添加了一个 Repeater 控件。该 Repeater 是数据绑定控件,用于按照自定义布局显示数据。这是显示来自 RSS 源的内容项列表的最佳方式。如下所示,在设计时,可以使用与该控件相关联的智能标记菜单为该控件设置数据源。但是,对于此应用程序,我将在运行时使用 RSS 源来设置数据源。


切换到 .ascx 文件的代码分离文件 (RSSList.ascx.vb),然后添加 Imports 语句,以便导入包含必要类 [在获取 RSS 源并将它存储到本地资源(将绑定到 Repeater)中时必须使用这些类] 的命名空间。

Imports System.Net
Imports System.Data

除了使用该控件的 Page Load 事件的事件处理程序之外,我还添加了名为 RefreshFeed 的专用帮助器函数。此函数获取 RSS 数据,并将该数据作为 DataSet 返回给 Page Load 事件处理程序。在 RefreshFeed 函数中,第一行代码使用 WebRequest 类的共享 Create 函数创建一个 HttpWebRequest 实例。

Dim rssFeed As HttpWebRequest =
DirectCast(WebRequest.Create("http://msdn.microsoft.com/vbasic/rss.xml"), HttpWebRequest)

作为 Create 函数的输入参数,该代码将传递 RSS 源的目标 URL。该函数返回一个 HttpWebRequest 对象,而该对象是一种特殊的 WebRequest 对象,它支持一些额外的属性和方法,可以通过 HTTP 与服务器交互。在这种情况下,我的需要对于 HttpWebRequest 来说非常简单;代码首先从服务器获取响应 (GetResponse),然后由于响应的格式为 XML 格式,因此可以使用接受 Stream 作为输入参数的 ReadXml 重载方法将响应流 (GetResponseStream) 直接加载到 DataSet 中。

Dim rssData As DataSet = New DataSet()
rssData.ReadXml(rssFeed.GetResponse().GetResponseStream())

ReadXml 方法会自动推断 XML 数据的架构。这意味着源 XML 数据的 <channel> 和 <items> 节点在 DataSet 中被表示为单独的 DataTable。在 Page Load 事件处理程序中,调用 RefereshFeed 方法以返回包含 RSS 源数据的 DataSet 之后,代码将以不同的方式访问通道和项数据。DataSet 中的第二个 DataTable 包含通道信息。为了显示源标题和说明,代码使用 RowItemArray 属性从 DataTableObject 数组中复制第一行(同时也是仅有的一行)。然后,由于我要确保我找到了正确的数据列,代码分别向 Integer 类型的本地变量指定了标题和说明列的顺序位置。使用这些值,代码调用 Object 数组的 GetValue 方法,以便将与每一列相关的值存储到为该类定义的 Friend 字段中(我将在 Repeater 控件中使用这些值)。

Dim channelItems As Object() = rssData.Tables(1).Rows(0).ItemArray
Dim titleColumn As Integer = rssData.Tables(1).Columns("title").Ordinal
Dim descriptionColumn As Integer = rssData.Tables(1).Columns("description").Ordinal
Title = channelItems.GetValue(titleColumn).ToString()
Description = channelItems.GetValue(descriptionColumn).ToString()

接下来,代码将 Repeater 控件的 DataSource 属性设置为 DataSet 中的 DataTable(保留了来自 RSS 源的项内容)。最后,代码调用 RepeaterDatBind 方法将该数据源绑定到控件。

Repeater1.DataSource = rssData.Tables(2)
Repeater1.DataBind()

RssFeed.ascx 控件的源代码视图中,我为 Repeater 控件添加了模板,用于显示该数据。在 <HeaderTemplate> 中,代码以显示通道标题和说明的标头元素作为表的开始。

<HeaderTemplate>
<table border=0 style="width: 240px; font-size: x-small; color: black; font-family: Verdana;">
<thead>
<tr style="font-weight: bold;">
<td><%#Me.Title%></td>
</tr>
<tr style="font-style: italic;">
<td><%#Me.Description%></td>
</tr>
</thead>
</HeaderTemplate>

同样,在 <ItemTemplate> 中,代码显示了带有其相关链接的内容项的标题以及该项的说明。

<ItemTemplate>
<tr bgcolor="LightBlue"  >
<td>
<a target="article" style="text-decoration: none;
color: black;" href=<%# DataBinder.Eval(Container.DataItem, "link") %>>
<%# DataBinder.Eval(Container.DataItem, "title") %> </a>
</td>
</tr>
<tr bgcolor="Ivory">
<td style="color: CornFlowerBlue;">
<%# DataBinder.Eval(Container.DataItem, "description") %>
</td>
</tr>
</ItemTemplate>

作为最后并且非常必要的一步,我在 .ascx 页的顶部添加了一条 OutputCache 指令,以便将该控件的输入缓存一个小时。

<%@ OutputCache Duration="3600" VaryByParam="None" %>

这可以避免在每次用户访问包含该控件的页面时都执行一次 RefreshFeed 函数。如果我不这么做,则当有大量用户访问我的网站时,会给我的 Web 服务器和联合提供程序之间带来大量通讯。如果运行该应用程序,联合的内容将如下所示。


在以后的文章中,我将深入探讨在 Web 应用程序中使用联合 RSS 源的可能性。然后,我会鼓励您下载代码,并自己试一下。

Peter Bernhardt 是一位独立软件开发人员和架构师,居住在旧金山的海湾地区。他有多年使用 Microsoft 技术的经验,现在又开始重新关注 Word Basic。可通过将电子邮件发送至 peter@SharpSense.net 来与 Peter 取得联系。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多