簡單的 RSS Feed

 作者:Peter Bernhardt
3Leaf Development

2005 年 8 月

多年前我歸納出一個結論,就是我對這世界上的一切還是有無知之處。沒錯,其實從那樣的出發點來看世界,本身就已經是十分自負的態度,可是年少輕狂嘛,不過現在的我就十分謙卑了。其實,在網際網路的時代裡這個事實只是倍加突顯,像我就幾乎無法跟上網路上川流不息的情報、新知和看法等等。就連我專長的領域 Visual Basic、Visual C# 和 .NET Framework,我都不知如何跟上最新的開發腳步。

正因此,我在接下來幾篇文章裡想探索其他方式,來應用您可能早已熟悉的技術:RSS (全名 Really Simple Syndication),這項技術是個減輕資訊負荷過重的最佳利器。

在此先提供初學者一些資訊,一個網上百科全書網站 Wikpedia 對 RSS 的解釋是「網站內容的簡述與連至全文內容的連結。而這些資訊是利用 XML 檔案的形式來傳遞的,該檔案又稱 RSS Feed、Webfeed、RSS 資料流或 RSS 通道。又為了要方便資訊聯合,RSS 允許網站的常客使用新聞彙總工具來追蹤網站更新。」 (全文請見 Wikpedia 網站對 RSS 的說明)。

本文會從一個簡單的 RSS Feed讀取程式開始著手,讓您利用 Visual Web Developer 2005 Express Edition 親手建立Feed。我會建立一個控制項,用它擷取網站上的某個 RSS Feed並組織裡面的內容以顯示在網頁上。您當然也可將 RSS Feed讀取程式建置成 Windows 應用程式;如果您的目的是要收集資料供私人之用,則還可以利用免費的 RSS 用戶端應用程式 (例如,RSS ReaderSharpReader)。然而,在 Web 應用程式內採用聯合內容有其好處,它能讓您擴展自己建立的內容,並提供網站造訪者豐富的使用經驗。

在鑽研程式碼前,我們先來看一小段典型 RSS 2.0 檔案的程式碼。本範例中的聯合資訊提供者是 Microsoft 的 MSDN 網站,而我是將Feed用於 Visual Basic 內容。

<rss
  xmlns:msdn="http://msdn.microsoft.com/aboutmsdn/rss/"
  xmlns:dc="http://purl.org/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>

典型的Feed檔案裡面充滿著各種資訊,其中某些資訊會因聯合資訊提供者而異 (以 MSDN 的標題影像為例,它就不是標準資訊)。XML 結構裡靠近頂層的部分有一個 <channel> 節點,裡麪包含一個標題以及可用來介紹內容項目清單的描述。<channel> 節點下包含許多子 <item> 節點,以代表每個內容文章 (包括文章的標題、描述、發行日期與連至全文的連結)。

在 Visual Web Developer 2005 Express Edition 內建立新的網站後,我在裡面加入了一個 Web 使用者控制項,用它來顯示資訊。

按一下此處以放大影像

(按一下影像以放大)

ASP.NET 2.0 的功能之一,就是它支援 Visual Studio 2003 開發人員所熟悉的程式碼後置 (Code-Behind) 模型,也支援內嵌程式碼 (新功能),能讓您在 .aspx 或 .ascx 檔案內的 <script> 標籤裡撰寫所有的程式碼。雖然採用內嵌程式碼的方式並不會影響到 ASP.NET 頁面執行,但我個人比較喜歡程式碼後置模型,並且會在本範例裡採用這個方式。您也會發現,我是用 Visual Basic 來撰寫本應用程式的程式碼。

在設計工具裡,我加入了 Repeater 控制項,這個 Repeater 是一個資料繫結控制項,能使用自訂的版面配置來顯示資料,這在顯示來自 RSS Feed的內容項目清單時十分方便,您可使用與控制項關聯的智慧標籤功能表,在設計階段設定控制項的資料來源,如下圖所示。不過,就這個應用程式,我會在執行階段使用 RSS Feed來設定資料來源。

按一下此處以放大影像

(按一下影像以放大)

過來,切換到 .ascx 檔案 (RSSList.ascx.vb) 的程式碼後置檔,我為命名空間 (其中包含取得 RSS Feed時所需的類別) 加上Imports 陳述式,再把檔案儲存在會繫結到 Repeater 的本機資源。

 System.Net
 System.Data

而在控制項的 Page Load 事件方面,我使用事件處理常式,此外,我還加入了名為 RefreshFeed 的私用 Helper 函式。如此一來,就能取得 RSS 資料,並將它以 DataSet 傳回給 Page Load 事件處理常式。在 RefreshFeed 函式裡,第一行程式碼會使用 WebRequest 類別的共用 Create 函式,建立 HttpWebRequest 物件的執行個體。

 rssFeed  HttpWebRequest = (WebRequest.Create(), HttpWebRequest)

做為 Create 函式的輸入引數,程式碼會傳遞 RSS Feed的目標 URL,函式會傳回一個 HttpWebRequest 物件,此物件是一種特殊類型的 WebRequest 物件,能支援其他屬性和方法,以利用 HTTP 與伺服器進行互動。在本例中,我的需求對 HttpWebRequest 而言根本易如反掌,程式碼首先先取得伺服器的回應 (GetResponse),然後由於回應的格式是 XML,因此回應資料流 (GetResponseStream) 可以利用能以 Stream 作為輸入引數的 ReadXml 方法多載,直接載入到 DataSet

 rssData  DataSet =  DataSet()
rssData.ReadXml(rssFeed.GetResponse().GetResponseStream())

ReadXml 方法會自動推斷 XML 資料的結構描述,換言之,來源 XML 資料的 <channel> <items> 節點在 DataSet 裡是以個別的 DataTable 來呈現。在 Page Load 事件處理函式裡,呼叫 RefereshFeed 方法來傳回含有 RSS Feed資料的 DataSet 後,程式碼會以不同的方式來存取通道和項目資料。DataSet 裡的第二個 DataTable 含有通道資訊。為了顯示Feed的標題和描述,程式碼使用 RowItemArray 屬性,把第一行資料列從 DataTable 複製到一個 Object 陣列。接下來,我想確定資料欄的位置是正確的,所以讓程式碼將標題欄與描述欄的原本位置分別指派到 Integer 型別的本機變數。程式碼會採用這些值呼叫 Object 陣列的 GetValue 方法,將與每個資料欄相關的值儲存到專為類別定義的 Friend 欄位 (我在 Repeater 控制項裡會用到這些值)。

 channelItems  () = rssData.Tables(1).Rows(0).ItemArray
 titleColumn   = rssData.Tables(1).Columns().Ordinal
 descriptionColumn   = rssData.Tables(1).Columns().Ordinal

Title = channelItems.GetValue(titleColumn).ToString()
 = channelItems.GetValue(descriptionColumn).ToString()

再過來,程式碼會在含有來自 RSS Feed之項目內容的 DataSet 中,將 Repeater 控制項的 DataSource 屬性設定為 DataTable。最後,程式碼會呼叫 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 Feed,但在那之前,我建議您下載本篇的範例程式碼,親自動手試看看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章