Coding4Fun: 一个简单的 RSS 源发布日期: 10/27/2005 | 更新日期: 10/27/2005
Peter Bernhardt 很多年以前,我得到一个经验:我不需要了解所有事情就能了解整个世界。当然,得出这个结论本身就是一种自大的行为。但是这种自大源于年轻无知,现在我更清楚地认识到了这一点。实际上,这个事实只有在 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 包含通道信息。为了显示源标题和说明,代码使用 Row 的 ItemArray 属性从 DataTable 向 Object 数组中复制第一行(同时也是仅有的一行)。然后,由于我要确保我找到了正确的数据列,代码分别向 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 源的项内容)。最后,代码调用 Repeater 的 DatBind 方法将该数据源绑定到控件。 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 取得联系。 |
|