天天看點

用ASP.NET建立一個線上RSS新聞聚合器(4)

第一步是建立一個html頁面來建立架構使用者界面。幸運的是,在Visual Studio.NET 2003 中,這一過程非常容易。隻需要在Web應用程式解決方案中添加一個新 的項目,選擇新項目類型為 Frameset。(我在我的工程中将這個新檔案命名為 NewsAggregator.htm。我之是以将它設定為 html 檔案而不是 asp.net 頁面, 是因為這個頁面隻包括建立架構的 html 代碼。每一個單獨的架構會顯示一個 asp.net 頁面)。下一步,參見圖三,Frameset 模版向導會啟動,簡單地選擇選項“Nested Hierarchy”,然後按ok按鈕就可以了。

用ASP.NET建立一個線上RSS新聞聚合器(4)

   然後 Frameset 模版向導會建立一個HTML頁面,裡面已經加入了架構的源代碼。 隻要将左邊架構的src屬性設定為 DisplayFeeds.aspx,它是清單顯示聚合摘要 asp.net 頁面的 url。至此 NewsAggreator.htm 頁面就完成了。

    以下三個部分,我們将講述如何建立線上新聞聚合器的三個元件,它們分别是顯示聚合摘要清單的 DisplayFeeds.aspx;顯示特定聚合摘要新聞項 的 DisplayNewsItems.aspx;以及顯示指定聚合摘要特定新聞項具體内容的 DisplayItem.aspx。

    顯示聚合摘要清單

    現在我們需要建立 DisplayFeeds.aspx 頁面。該頁面要顯示訂閱的聚合摘要清單。作為示範,我将這些聚合摘要放在一個叫 Feeds 的資料庫表中。當然你也可以将它們放在一個XML檔案中。表 Feeds 有如下四個字段:

    ·FeedID—主鍵,自增長整數類型,唯一标示一個摘要

    ·Title—摘要名稱,資料庫字段類型:varchar(50)

    ·URL—RSS 摘要的 URL,資料庫字段類型:varchar(150)

    ·UpdateInterval—摘要更新頻率(分鐘),資料庫字段類型:int

    DisplayFeeds.aspx 頁面使用一個 DataGrid 控件顯示聚合摘要的清單。這個 DataGrid 隻有一個 HyperLinkColumn 列,顯示 Title 字段的内容并且連結到 DisplayNewsItems.aspx 頁面, 在查詢字元串中 要傳遞 FeedID 字段的值。以下是 DataGrid 控件的聲明,為簡單起見,省略了一些無關的部分):

  <asp:DataGrid id="dgFeeds" runat="server"

  AutoGenerateColumns="False" ...>

  ...

  <Columns>

  <asp:HyperLinkColumn Target="rtop"

  DataNavigateUrlField="FeedID"

  DataNavigateUrlFormatString="DisplayNewsItems.aspx?FeedID={0}"

  DataTextField="Title" HeaderText="RSS Feeds">

  </asp:HyperLinkColumn>

  </Columns>

  </asp:DataGrid>

    這裡要注意的關鍵是 HyperLinkColumn 列的定義。它的 Target 屬性設定為右上部分架構的名稱,這樣當使用者點選的時候,DisplayNewsItems.aspx 頁面就會顯示在右上部分的架構中。另外, 屬性 DataNavigateUrlField、DataNavigateUrlFormatString 和 DataTextField 也做了相應的設定, 以便超連結顯示摘要的标題,并且當點選它時,就會将使用者帶到 DisplayNewsItems.aspx 頁面,并在查詢串中将 FeedID 字段的内容傳 過來。(該頁面的背景代碼類隻通路來自 Feeds 表的摘要清單,按照 Title 字段的字母順序傳回,接着将查詢結果綁定到 DataGrid 控件。 由于篇幅所限,本文在此不列出代碼。)

    顯示特定聚合摘要的新聞項

    我們面臨的下一個任務是建立 DisplayNewsItems.aspx 頁面。這個頁面會以連結的形式顯示所選聚合摘要的新聞項标題,當點選标題時,新聞的内容就會顯示在右下部分的架構中。要完成這一任務,我們會面臨以下兩個主要的挑戰:

    ·通過指定的 URL 通路 RSS 聚合摘要;

    ·将接收到的 XML 資料轉換為相應的 HTML;

    幸運的是,在.NET 架構中,要實作這兩個任務都不是很難。對于第一個任務,隻需要兩行代碼,我們就可以将遠端的xml資料裝載到一個XmlDocument對象中。而第二個任務呢, 借助 ASP.NET XML Web 控件在ASP.NET 頁面中顯示XML資料也比較容易。

    XML Web 控件被設計用于在 Web 頁面中顯示原始或者轉換過的 XML 資料。使用 XML Web 控件的第一步是定義XML資料源,通過 定義一系列的屬性,用許多方法都可以完成這一工作。使用 Document屬性,你可以指定一個 XmlDocument 執行個體作為 XML Web 控件的 XML 資料源。如果XML資料存在于 Web 伺服器檔案系統的一個檔案中,可以用 DocumentSource 屬性,隻要提供該 XML 檔案的相對或者絕對路徑就可以了。最後,如果你 的 XML資料是一個字元串,那麼你可以将這個字元串的内容賦給控件的 DocumentContent 屬性。這三種辦法都可以将 XML 資料與 XML 控件聯系起來。

    通常,在将 XML 資料顯示到 Web 頁面之前,我們會以某種方式轉換 XML 資料。XML Web 控件允許我們指定一個 XSLT 樣式表來做這個轉換工作。與 XML 資料相似,XSLT 樣式表可以通過 兩個屬性之一,以兩種不同的方式中的一種來設定,一是 Transform 屬性可被指派給 XslTransform 執行個體,二是将本地 Web 伺服器上 XSLT檔案的 相對或絕對路徑賦予 TransformSource 屬性。

    現在我們來建立 DisplayNewsItems.aspx 頁面。在添加 XML Web 控件以及編寫背景代碼類之前,我們需要在 HTML 部分加入一小段用戶端 JavaScript 代碼。準确地說,是在 html 部分的 <head> 标簽裡面 添加如下的<script>代碼塊:

  <script language="javascript">

  // display a blank page in the bottom frame when the news items loads

  parent.rbottom.location.href = "about:blank";

  </script>

    每當 DisplayNewsItems.aspx 頁面裝載的時候,這段用戶端 JavaScript 代碼會在右下角的架構中顯示一個空白頁。為了了解為什麼要加入這段代碼,我們來看看省略這段代碼,我們會碰到什麼情況:

    ·使用者在左邊的架構中點選聚合摘要,浏覽器會在右上部的架構中裝載摘要新聞項;

    ·使用者在右上部架構中點選某個新聞項,浏覽器會在右下部架構中裝載這個新聞項 的詳細内容;

    現在使用者在左邊的架構中點選其它的聚合摘要,浏覽器會在右上部分的架構中裝載新的摘要新聞項;

    前一個新聞項的詳細内容還顯示在右下部的架構中!通過上面的用戶端 Javascript 代碼,每次點選左面架構的摘要便可以清除右下部架構 的内容,以消除這一瑕疵。

    在我們處理了用戶端代碼的問題之後,讓我們把注意力轉到添加 XML Web 控件。一旦加入 XML Web 控件,将其 ID 屬性設定為 xsltNewsItems,TransformSourc 屬性設定為 NewsItems.xslt(我們将要建立的 XSLT 樣式表檔案的名稱)。現在,在 Page_Load 事件處理函數中,我們需要 在某個 XmlDocument 執行個體中擷取遠端 RSS 聚合檔案,然後将該 XML Web 控件的 Document 屬性賦給該 XmlDocument 執行個體。

    在 Page_Load 事件處理函數中,與我們要實作的任務有密切關系的代碼是最後三行代碼。這三行代碼建立一個新的 XmlDocument 對象, 加載遠端 RSS 摘要内容,然後将這個 XmlDocument 對象賦給 XML Web 控件的 Document 屬性。通路遠端 XML 資料并 将它們顯示在 ASP.NET 頁面中就是這麼簡單,難道給你留下的印象不深嗎?

    剩下我們要做的一件事就是建立 XSLT 樣式表,NewsItems.aspx。下面是樣式表的第一版的草稿:

  <?xml version="1.0" encoding="UTF-8" ?>

  <xsl:stylesheet version="1.0"

  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" omit-xml-declaration="yes" />

  <xsl:template match="/rss/channel">

  <b><xsl:value-of select="title"

  disable-output-escaping="yes" /></b>

  <xsl:for-each select="item">

  <li>

  <a>

  <xsl:attribute name="href">

  DisplayItem.aspx?ID=<xsl:number value="position()" />

  </xsl:attribute>

  <xsl:attribute name="target">rbottom</xsl:attribute>

  <xsl:value-of select="title"

  disable-output-escaping="yes" />

  </a>

  (<xsl:value-of select="pubDate" />)

  </li>

  </xsl:for-each>

  </xsl:template>

  </xsl:stylesheet>