最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

用 Asp.Net 建立一個(gè)在線 RSS 新聞聚合器的方法

來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:45:35
文檔

用 Asp.Net 建立一個(gè)在線 RSS 新聞聚合器的方法

用 Asp.Net 建立一個(gè)在線 RSS 新聞聚合器的方法:隨著辦公室和家庭上網(wǎng)在線時(shí)間的延長(zhǎng),以及 Web 站點(diǎn)和可訪問的互聯(lián)網(wǎng)應(yīng)用程序呈持續(xù)爆炸性增長(zhǎng),應(yīng)用程序之間能數(shù)據(jù)共享變得越來越重要。在異構(gòu)平臺(tái)之間共享數(shù)據(jù)需要一種平臺(tái)中立的數(shù)據(jù)格式,這種數(shù)據(jù)格式要求能易于通過標(biāo)準(zhǔn)的互聯(lián)網(wǎng)協(xié)議來傳輸,而這正是X
推薦度:
導(dǎo)讀用 Asp.Net 建立一個(gè)在線 RSS 新聞聚合器的方法:隨著辦公室和家庭上網(wǎng)在線時(shí)間的延長(zhǎng),以及 Web 站點(diǎn)和可訪問的互聯(lián)網(wǎng)應(yīng)用程序呈持續(xù)爆炸性增長(zhǎng),應(yīng)用程序之間能數(shù)據(jù)共享變得越來越重要。在異構(gòu)平臺(tái)之間共享數(shù)據(jù)需要一種平臺(tái)中立的數(shù)據(jù)格式,這種數(shù)據(jù)格式要求能易于通過標(biāo)準(zhǔn)的互聯(lián)網(wǎng)協(xié)議來傳輸,而這正是X

隨著辦公室和家庭上網(wǎng)在線時(shí)間的延長(zhǎng),以及 Web 站點(diǎn)和可訪問的互聯(lián)網(wǎng)應(yīng)用程序呈持續(xù)爆炸性增長(zhǎng),應(yīng)用程序之間能數(shù)據(jù)共享變得越來越重要。在異構(gòu)平臺(tái)之間共享數(shù)據(jù)需要一種平臺(tái)中立的數(shù)據(jù)格式,這種數(shù)據(jù)格式要求能易于通過標(biāo)準(zhǔn)的互聯(lián)網(wǎng)協(xié)議來傳輸,而這正是XML的用武之地。因?yàn)閄ML文件本質(zhì)上只是一個(gè)文本文件,其編碼格式眾所周知,而且現(xiàn)有的XML解析器能為所有主流編程語言所用,所以XML數(shù)據(jù)能被任何平臺(tái)輕松使用。 

  Web 網(wǎng)站聚合就是一種使用 XML 來共享數(shù)據(jù)的范例,在新聞?wù)军c(diǎn)和網(wǎng)志中經(jīng)??梢钥吹健2捎?nbsp;Web 網(wǎng)站聚合技術(shù),網(wǎng)站能以 XML 格式的 Web 可訪問的聚合文件來發(fā)布最新內(nèi)容。網(wǎng)站使用的聚合格式有很多種,其中最流行的一種格式就是 RSS2.0。( RSS2.0 規(guī)范被發(fā)布在 Harvard Law 網(wǎng)站 的技術(shù)欄目上)。此外,MSDN 雜志有一個(gè)聚合文件:MSDN雜志:本期刊物, 其中列出了最新一期 MSDN 雜志上的文章,包括到在線版本文章的鏈接。 

  一旦 Web 站點(diǎn)有了公開發(fā)布聚合文件,那么不同的客戶端就可以消費(fèi)它。消費(fèi)聚合文件的方式有很多種,比如,某個(gè)提供 .NET 技術(shù)資源的站點(diǎn)可能希望在網(wǎng)站中 添加最新的 MSDN 雜志文章標(biāo)題。聚合文件還常常被新聞聚合器程序所用,這種程序被專門設(shè)計(jì)用來獲取和顯示不同來源的聚合文件。 

  隨著人們?cè)絹碓阶⒅厥褂?nbsp;XML 數(shù)據(jù),在 ASP.NET 頁(yè)面中處理 XML 數(shù)據(jù)的能力變得比以往更關(guān)鍵。既然 Web 站點(diǎn)聚合如此重要, 本文我們就來創(chuàng)建一個(gè) Web 站點(diǎn)聚合文件生成程序和一個(gè)在線新聞聚合器。在建立這兩個(gè)微型程序的過程中,我們將講述如何訪問和顯示XML數(shù)據(jù),不論這些數(shù)據(jù)是來自遠(yuǎn)端的Web服務(wù)器還是本地的文件系統(tǒng)。我們將演示如 何多種不同的方法顯示XML數(shù)據(jù),比如:用 Repeater 控件以及用 ASP.NET XML Web控件。

使用 RSS 2.0 規(guī)范的聚合內(nèi)容

  本文我們將要?jiǎng)?chuàng)建的第一個(gè)微型程序是一個(gè)聚合文件生成器。針對(duì)這個(gè)迷你程序,假設(shè)你是一個(gè)大型新聞網(wǎng)站(如 MSNBC.com)的 Web 開發(fā)者,所有的新聞內(nèi)容都保存在 Microsoft SQL Server 2000 數(shù)據(jù)庫(kù)中。具體地說,這些文章是 都保存在一個(gè)名為 Articles 的表中,表中以下字段與我們的程序密切相關(guān):

ArticleID—主鍵,自增長(zhǎng)的整型字段,用來唯一標(biāo)識(shí)每一篇文章; 
Title— 指定標(biāo)題,字段數(shù)據(jù)類型: varchar(50); 
Author—指定作者,字段數(shù)據(jù)類型: varchar(50); 
Description—新聞內(nèi)容描述,字段數(shù)據(jù)類型: varchar(2000); 
DatePublished—新聞發(fā)布日期,字段數(shù)據(jù)類型:datetime 

  請(qǐng)注意,Articles 表中可能還有其它字段,上面所列的只是我們?cè)趧?chuàng)建聚合文件的時(shí)候所要用到的字段。而且,這只是一個(gè)非常簡(jiǎn)單的數(shù)據(jù)模型,在 是應(yīng)用的數(shù)據(jù)庫(kù)環(huán)境中,你可能會(huì)使用更加標(biāo)準(zhǔn)化的數(shù)據(jù)庫(kù)模型,比如具備一個(gè)單獨(dú)的 authors (作者)表,有一個(gè)建立作者和文章之間多對(duì)多關(guān)系的表等等。

  下一步,我們將創(chuàng)建一個(gè)ASP.NET頁(yè)面,用格式化好的 RSS2.0 XML 文件顯示一個(gè)最新的新聞列表。在講述如何在 ASP.NET 頁(yè)面 中完成這種轉(zhuǎn)換之前,我們要先介紹一下 RSS2.0 規(guī)范的內(nèi)容。我們應(yīng)該記住,在整個(gè)規(guī)范中,RSS 是被設(shè)計(jì)用來為聚合內(nèi)容提供一個(gè)數(shù)據(jù)模型。那么 毫無疑問,它會(huì)有一系列的 XML 元素,用來描述 Web 站點(diǎn)要聚合的內(nèi)容信息,以及一系列用來描述某一特定新聞項(xiàng)的 XML 元素。最后,不要忘記 RSS 聚合文件是一個(gè) XML 格式文件,必須符合 XML 格式化的準(zhǔn)則, 也就是: 

所有 XML元素必須正確嵌套; 
所有的屬性值要用引號(hào)包含起來; 
<, >, &, "和''符號(hào)要相應(yīng)地替換為 <,>, &, " 和 '; 
  而且,XML格式是大小寫敏感的,這就意味著,XML元素的起始和終止標(biāo)簽必須匹配,拼寫和大小寫都必須一致。 
  RSS2.0 的根元素是<rss>元素,這個(gè)元素可以有一個(gè)版本號(hào)的屬性,例如:

<rss version="2.0">
...
</rss>

<rss>元素只有一個(gè)子元素<channel>,用來描述聚合的內(nèi)容。在<channel>元素里面有三個(gè)必需的子元素,用來描述 Web 站點(diǎn)的信息。這三個(gè)元素是: 

title—定義聚合文件的名稱,一般來說,還會(huì)包括Web站點(diǎn)的名稱; 
link—Web站點(diǎn)的URL; 
description—Web站點(diǎn)的一段簡(jiǎn)短的描述。 
除此之外,還有一些可選元素來描述站點(diǎn)信息。這些元素的更多信息請(qǐng)參見 RSS2.0規(guī)范。 

每一個(gè)新聞項(xiàng)目放在一個(gè)單獨(dú)的<item>元素中。<channel>元素可以有任意數(shù)量的<item>元素。每個(gè)<item>元素可以有多種的子元素,唯一的要求是最少必須包含<title>元素和<description>元素其中一個(gè)作為子元素。以下列出了一些相關(guān)的<item> 子元素: 

title—新聞項(xiàng)目的標(biāo)題; 
link—新聞項(xiàng)目的URL; 
description—新聞項(xiàng)目的大綱; 
author—新聞項(xiàng)目的作者; 
pubDate—新聞項(xiàng)目的發(fā)布日期 
  下面是一個(gè)非常簡(jiǎn)單的 RSS2.0 聚合文件。你可以從 RSS generated by Radio UserLand 看到其他的RSS2.0文件的例子。

<rss version="2.0">
<channel>
<title>Latest DataWebControls.com FAQs</title>
<link>http://datawebcontrols.com</link>
<description>
This is the syndication feed for the FAQs 
at DataWebControls.com
</description>
<item>
<title>Working with the DataGrid</title>
<link>http://datawebcontrols.com/faqs/DataGrid.aspx</link>
<pubDate>Mon, 07 Jul 2003 21:00:00 GMT</pubDate>
</item>
<item>
<title>Working with the Repeater</title>
<description>
This article examines how to work with the Repeater 
control.
</description>
<link>http://datawebcontrols.com/faqs/Repeater.aspx</link>
<pubDate>Tue 08 Jul 2003 12:00:00 GMT</pubDate>
</item>
</channel>
</rss> 

  關(guān)于<pubDate>元素的格式有一點(diǎn)特別重要,再此要講一下。RSS 要求日期必須按照 RFC822 日期和時(shí)間規(guī)范 進(jìn)行格式化,此格式要求:開頭是一個(gè)可選的3字母星期縮寫加一個(gè)逗號(hào),接著必須是日加上3字母縮寫的月份和年份,最后是一個(gè)帶時(shí)區(qū)名的時(shí)間。另外,要注意 <description> 子元素是可選的:上 述文件第一個(gè)新聞沒有 <description> 元素,而第二個(gè)新聞就有一個(gè)。

通過 ASP.NET 頁(yè)面輸出聚合內(nèi)容

  現(xiàn)在,我們已經(jīng)知道了如何按照 RSS2.0 規(guī)范存儲(chǔ)我們的新聞項(xiàng),我們已經(jīng)就緒創(chuàng)建一個(gè) ASP.NET 頁(yè)面,當(dāng)用戶發(fā)出請(qǐng)求時(shí),就會(huì)返回網(wǎng)站聚合 的內(nèi)容。更確切地說,我們將建立一個(gè)名字叫 rss.aspx 的 ASP.NET 頁(yè)面,這個(gè)頁(yè)面會(huì)按照 RSS2.0 規(guī)范的格式返回 Articles 數(shù)據(jù)庫(kù)表中的最新的 5 個(gè)新聞項(xiàng) 。

  可以有幾種方法來完成這件事,稍后將會(huì)講到。但是現(xiàn)在,我們首先要完成一件事,那就是先要從數(shù)據(jù)庫(kù)中獲得最新的5個(gè)新聞項(xiàng)。這可以用下面的 SQL 查詢語句獲得:

SELECT TOP 5 ArticleID,Title,Author,Description,DatePublished FROM Articles ORDER BY DatePublished DESC

  獲得了這些信息以后,我們需要把這些信息轉(zhuǎn)換成相應(yīng)的 RSS2.0 格式聚合文件。要把數(shù)據(jù)庫(kù)的數(shù)據(jù)顯示為XML數(shù)據(jù)最簡(jiǎn)單、快速的方法就是使用 Repeater 控件。準(zhǔn)確地說,Repeater 控件 將在 HeaderTemplate 和 FooterTemplate 模版里顯示<rss>元素、<channel>元素以及站點(diǎn)相關(guān)的 元素標(biāo)簽,在 ItemTemplate 模版里面顯示 <item> 元素。下面是我們這個(gè) ASP.NET 頁(yè)面(.aspx文件)的 HTML 部分 :

<%@ Page language="c#" ContentType="text/xml" Codebehind="rss.aspx.cs"
AutoEventWireup="false" Inherits="SyndicationDemo.rss" %>
<asp:Repeater id="rptRSS" runat="server">
<HeaderTemplate>
<rss version="2.0">
<channel>
<title>ASP.NET News!</title>
<link>http://www.ASPNETNews.com/Headlines/</link>
<description>
This is the syndication feed for ASPNETNews.com.
</description>
</HeaderTemplate>

<ItemTemplate>
<item>
<title><%# FormatForXML(DataBinder.Eval(Container.DataItem,
"Title")) %></title>
<description>
<%# FormatForXML(DataBinder.Eval(Container.DataItem, 
"Description")) %>
</description>
<link>
http://www.ASPNETNews.com/Story.aspx?ID=<%# 
DataBinder.Eval(Container.DataItem, "ArticleID") %>
</link>
<author><%# FormatForXML(DataBinder.Eval(Container.DataItem, 
"Author")) %></author>
<pubDate>
<%# String.Format("{0:R}", 
DataBinder.Eval(Container.DataItem, 
"DatePublished")) %>
</pubDate>
</item>
</ItemTemplate>

<FooterTemplate>
</channel>
</rss> 
</FooterTemplate>
</asp:Repeater> 

  首先要注意的是:上面這段代碼例子只包括 Repeater 控件,沒有其它的 HTML 標(biāo)記或 Web 控件。這是因?yàn)槲覀兿M?yè)面只輸出 XML 格式的數(shù)據(jù)。實(shí)際上,觀察一下 @Page 指令,你就會(huì)發(fā)現(xiàn) ContentType 被設(shè)置為XML MIME 類型(text/xml)。其次要注意的是:在 ItemTemplate 模版里,當(dāng) 在 XML 輸出中添加數(shù)據(jù)庫(kù)字段Title、Description 和 Author 時(shí),我們調(diào)用了輔助函數(shù) FormatForXML()。我們 很快就會(huì)看到,該函數(shù)被定義在后臺(tái)編碼的類中,其作用只是將非法的 xml 字符替換為它們對(duì)應(yīng)的合法的轉(zhuǎn)義字符。最后我們應(yīng)該注意,在 <pubDate> 元素里面的數(shù)據(jù)庫(kù)字段 DatePublished 是用 String.Format 來格式化的。標(biāo)準(zhǔn)的格式描述符“R”對(duì) DatePublished 的值進(jìn)行相應(yīng)的格式化 。

  此 Web 頁(yè)面的后臺(tái)編碼類代碼并不復(fù)雜。Page_Load 事件處理函數(shù)只是將數(shù)據(jù)庫(kù)查詢結(jié)果綁定到 Repeater控件,F(xiàn)ormatForXML()函數(shù)根據(jù)需要做一些簡(jiǎn)單的字符串替換。為 簡(jiǎn)單起見,下面的例子只列出了這兩個(gè)函數(shù)的代碼:

  在瀏覽器中訪問 rss.aspx 頁(yè)面的截圖參見圖一。


圖一 通過瀏覽器訪問 Rss.aspx 頁(yè)面 

  在我們生成在線新聞聚合器之前,讓我談?wù)勥@個(gè)聚合引擎一些可能的增強(qiáng)功能。首先,每一次訪問 rss.aspx 頁(yè)面的時(shí)候,都要訪問一次數(shù)據(jù)庫(kù)。如果預(yù)期可能有大量的人頻繁地訪問 rss.aspx 頁(yè)面,使用輸出緩存是很有價(jià)值的。其次,通常新聞網(wǎng)站會(huì)將聚合的內(nèi)容分為不同的類別。例如:News.com 有一些專門的聚合內(nèi)容區(qū), 比如針對(duì)企業(yè)計(jì)算、電子商務(wù)、通信的內(nèi)容等等。在數(shù)據(jù)庫(kù)表 Articles 中加入表示類別的 Category 字段就可以很容易地提供這種支持。這樣 一來,在 rss.aspx 頁(yè)面中,可以接收一個(gè)表示顯示分類的查詢參數(shù),然后只搜索指定的新聞項(xiàng)分類即可。 

在 ASP.NET 頁(yè)面中使用聚合摘要

  為了測(cè)試我們剛建立的聚合引擎,我們將創(chuàng)建一個(gè)在線新聞聚合器,允許采集任意數(shù)量的聚合內(nèi)容摘要。聚合器的界面很簡(jiǎn)單,參見圖二。它包括三個(gè)框架頁(yè)面。左邊框架以列表形式列出了不同的聚合內(nèi)容摘要。右上部框架顯示所選的聚合內(nèi)容摘要包含的新聞項(xiàng)以及查看該新聞項(xiàng)的鏈接。最后,在右下部框架則顯示選中的新聞項(xiàng)標(biāo)題和內(nèi)容。順便提及一下,這樣的界面基本上是各種類型的聚合器的一個(gè)事實(shí)上的標(biāo)準(zhǔn)界面,包括新聞聚合器、email客戶端軟件和新聞組閱讀器都是這樣的界面。


圖二 新聞聚合器用戶界面的截圖 

  第一步是創(chuàng)建一個(gè)html頁(yè)面來建立框架用戶界面。幸運(yùn)的是,在Visual Studio.NET 2003 中,這一過程非常容易。只需要在Web應(yīng)用程序解決方案中添加一個(gè)新 的項(xiàng)目,選擇新項(xiàng)目類型為 Frameset。(我在我的工程中將這個(gè)新文件命名為 NewsAggregator.htm。我之所以將它設(shè)置為 html 文件而不是 asp.net 頁(yè)面, 是因?yàn)檫@個(gè)頁(yè)面只包括建立框架的 html 代碼。每一個(gè)單獨(dú)的框架會(huì)顯示一個(gè) asp.net 頁(yè)面)。下一步,參見圖三,F(xiàn)rameset 模版向?qū)?huì)啟動(dòng),簡(jiǎn)單地選擇選項(xiàng)“Nested Hierarchy”,然后按ok按鈕就可以了。 


圖三 VS2003 中 Frameset 模版向?qū)М嬅?

  然后 Frameset 模版向?qū)?huì)創(chuàng)建一個(gè)HTML頁(yè)面,里面已經(jīng)加入了框架的源代碼。 只要將左邊框架的src屬性設(shè)置為 DisplayFeeds.aspx,它是列表顯示聚合摘要 asp.net 頁(yè)面的 url。至此 NewsAggreator.htm 頁(yè)面就完成了。 

  以下三個(gè)部分,我們將講述如何創(chuàng)建在線新聞聚合器的三個(gè)組件,它們分別是顯示聚合摘要列表的 DisplayFeeds.aspx;顯示特定聚合摘要新聞項(xiàng) 的 DisplayNewsItems.aspx;以及顯示指定聚合摘要特定新聞項(xiàng)具體內(nèi)容的 DisplayItem.aspx。

顯示聚合摘要列表 

  現(xiàn)在我們需要?jiǎng)?chuàng)建 DisplayFeeds.aspx 頁(yè)面。該頁(yè)面要顯示訂閱的聚合摘要列表。作為示范,我將這些聚合摘要放在一個(gè)叫 Feeds 的數(shù)據(jù)庫(kù)表中。當(dāng)然你也可以將它們放在一個(gè)XML文件中。表 Feeds 有如下四個(gè)字段: 

FeedID—主鍵,自增長(zhǎng)整數(shù)類型,唯一標(biāo)示一個(gè)摘要 
Title—摘要名稱,數(shù)據(jù)庫(kù)字段類型:varchar(50) 
URL—RSS 摘要的 URL,數(shù)據(jù)庫(kù)字段類型:varchar(150) 
UpdateInterval—摘要更新頻率(分鐘),數(shù)據(jù)庫(kù)字段類型:int 
DisplayFeeds.aspx 頁(yè)面使用一個(gè) DataGrid 控件顯示聚合摘要的列表。這個(gè) DataGrid 只有一個(gè) HyperLinkColumn 列,顯示 Title 字段的內(nèi)容并且鏈接到 DisplayNewsItems.aspx 頁(yè)面, 在查詢字符串中 要傳遞 FeedID 字段的值。以下是 DataGrid 控件的聲明,為簡(jiǎn)單起見,省略了一些無關(guān)的部分):

<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> 

  這里要注意的關(guān)鍵是 HyperLinkColumn 列的定義。它的 Target 屬性設(shè)置為右上部分框架的名稱,這樣當(dāng)用戶點(diǎn)擊的時(shí)候,DisplayNewsItems.aspx 頁(yè)面就會(huì)顯示在右上部分的框架中。另外, 屬性 DataNavigateUrlField、DataNavigateUrlFormatString 和 DataTextField 也做了相應(yīng)的設(shè)置, 以便超鏈接顯示摘要的標(biāo)題,并且當(dāng)點(diǎn)擊它時(shí),就會(huì)將用戶帶到 DisplayNewsItems.aspx 頁(yè)面,并在查詢串中將 FeedID 字段的內(nèi)容傳 過來。(該頁(yè)面的后臺(tái)代碼類只訪問來自 Feeds 表的摘要清單,按照 Title 字段的字母順序返回,接著將查詢結(jié)果綁定到 DataGrid 控件。 由于篇幅所限,本文在此不列出代碼。)

顯示特定聚合摘要的新聞項(xiàng)

  我們面臨的下一個(gè)任務(wù)是創(chuàng)建 DisplayNewsItems.aspx 頁(yè)面。這個(gè)頁(yè)面會(huì)以鏈接的形式顯示所選聚合摘要的新聞項(xiàng)標(biāo)題,當(dāng)點(diǎn)擊標(biāo)題時(shí),新聞的內(nèi)容就會(huì)顯示在右下部分的框架中。要完成這一任務(wù),我們會(huì)面臨以下兩個(gè)主要的挑戰(zhàn): 

  通過指定的 URL 訪問 RSS 聚合摘要;
  將接收到的 XML 數(shù)據(jù)轉(zhuǎn)換為相應(yīng)的 HTML; 

  幸運(yùn)的是,在.NET 框架中,要實(shí)現(xiàn)這兩個(gè)任務(wù)都不是很難。對(duì)于第一個(gè)任務(wù),只需要兩行代碼,我們就可以將遠(yuǎn)程的xml數(shù)據(jù)裝載到一個(gè)XmlDocument對(duì)象中。而第二個(gè)任務(wù)呢, 借助 ASP.NET XML Web 控件在ASP.NET 頁(yè)面中顯示XML數(shù)據(jù)也比較容易。

  XML Web 控件被設(shè)計(jì)用于在 Web 頁(yè)面中顯示原始或者轉(zhuǎn)換過的 XML 數(shù)據(jù)。使用 XML Web 控件的第一步是定義XML數(shù)據(jù)源,通過 定義一系列的屬性,用許多方法都可以完成這一工作。使用 Document屬性,你可以指定一個(gè) XmlDocument 實(shí)例作為 XML Web 控件的 XML 數(shù)據(jù)源。如果XML數(shù)據(jù)存在于 Web 服務(wù)器文件系統(tǒng)的一個(gè)文件中,可以用 DocumentSource 屬性,只要提供該 XML 文件的相對(duì)或者絕對(duì)路徑就可以了。最后,如果你 的 XML數(shù)據(jù)是一個(gè)字符串,那么你可以將這個(gè)字符串的內(nèi)容賦給控件的 DocumentContent 屬性。這三種辦法都可以將 XML 數(shù)據(jù)與 XML 控件聯(lián)系起來。

  通常,在將 XML 數(shù)據(jù)顯示到 Web 頁(yè)面之前,我們會(huì)以某種方式轉(zhuǎn)換 XML 數(shù)據(jù)。XML Web 控件允許我們指定一個(gè) XSLT 樣式表來做這個(gè)轉(zhuǎn)換工作。與 XML 數(shù)據(jù)相似,XSLT 樣式表可以通過 兩個(gè)屬性之一,以兩種不同的方式中的一種來設(shè)置,一是 Transform 屬性可被賦值給 XslTransform 實(shí)例,二是將本地 Web 服務(wù)器上 XSLT文件的 相對(duì)或絕對(duì)路徑賦予 TransformSource 屬性。

  現(xiàn)在我們來創(chuàng)建 DisplayNewsItems.aspx 頁(yè)面。在添加 XML Web 控件以及編寫后臺(tái)代碼類之前,我們需要在 HTML 部分加入一小段客戶端 JavaScript 代碼。準(zhǔn)確地說,是在 html 部分的 <head> 標(biāo)簽里面 添加如下的<script>代碼塊:

<script language="javascript">
// display a blank page in the bottom frame when the news items loads
parent.rbottom.location.href = "about:blank";
</script> 

  每當(dāng) DisplayNewsItems.aspx 頁(yè)面裝載的時(shí)候,這段客戶端 JavaScript 代碼會(huì)在右下角的框架中顯示一個(gè)空白頁(yè)。為了理解為什么要加入這段代碼,我們來看看省略這段代碼,我們會(huì)碰到什么情況: 

  用戶在左邊的框架中點(diǎn)擊聚合摘要,瀏覽器會(huì)在右上部的框架中裝載摘要新聞項(xiàng);
  用戶在右上部框架中點(diǎn)擊某個(gè)新聞項(xiàng),瀏覽器會(huì)在右下部框架中裝載這個(gè)新聞項(xiàng) 的詳細(xì)內(nèi)容;
  現(xiàn)在用戶在左邊的框架中點(diǎn)擊其它的聚合摘要,瀏覽器會(huì)在右上部分的框架中裝載新的摘要新聞項(xiàng); 

  現(xiàn)在,前一個(gè)新聞項(xiàng)的詳細(xì)內(nèi)容還顯示在右下部的框架中!通過上面的客戶端 Javascript 代碼,每次點(diǎn)擊左面框架的摘要便可以清除右下部框架 的內(nèi)容,以消除這一瑕疵。

  現(xiàn)在我們處理了客戶端代碼的問題之后,讓我們把注意力轉(zhuǎn)到添加 XML Web 控件。一旦加入 XML Web 控件,將其 ID 屬性設(shè)置為 xsltNewsItems,TransformSourc 屬性設(shè)置為 NewsItems.xslt(我們將要?jiǎng)?chuàng)建的 XSLT 樣式表文件的名稱)?,F(xiàn)在,在 Page_Load 事件處理函數(shù)中,我們需要 在某個(gè) XmlDocument 實(shí)例中獲取遠(yuǎn)程 RSS 聚合文件,然后將該 XML Web 控件的 Document 屬性賦給該 XmlDocument 實(shí)例。

  在 Page_Load 事件處理函數(shù)中,與我們要實(shí)現(xiàn)的任務(wù)有密切關(guān)系的代碼是最后三行代碼。這三行代碼創(chuàng)建一個(gè)新的 XmlDocument 對(duì)象, 加載遠(yuǎn)程 RSS 摘要內(nèi)容,然后將這個(gè) XmlDocument 對(duì)象賦給 XML Web 控件的 Document 屬性。訪問遠(yuǎn)程 XML 數(shù)據(jù)并 將它們顯示在 ASP.NET 頁(yè)面中就是這么簡(jiǎn)單,難道給你留下的印象不深嗎? 

  剩下我們要做的一件事就是創(chuàng)建 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> 

  這個(gè)XSLT樣式表只有一個(gè)模版,用于匹配“/rss/channel”XPath表達(dá)式。這個(gè)模版先是以粗體顯示<title>元素的內(nèi)容。然后,循環(huán)獲取每一個(gè)<item>元素,對(duì)于每一個(gè)元素,顯示一個(gè)到 DisplayItem.aspx 頁(yè)面的超鏈接,在查詢字符串中傳遞<item>元素的位置屬性。要留意超鏈接的 target 屬性設(shè)置為 rbottom,右下部框架的名稱。最后,顯示每一個(gè)新聞項(xiàng)的標(biāo)題和<pubDate>元素。

  該 XSLT 樣式表中有兩個(gè)項(xiàng)目,并不是每個(gè)人都熟悉。首先是 <xsl:value-of> 元素中的 disable-output-escaping="yes" 屬性。從本質(zhì)上講,這個(gè)屬性的設(shè)置通知 XSLT 引擎不要轉(zhuǎn)義那些非法的 XML 字符,比如:&, < , >, " 和 ''。為了理解這個(gè)設(shè)置的意義,就要知道,如果不設(shè)置該屬性(也就是設(shè)置為默認(rèn)值"no"),那么如果標(biāo)題包含一個(gè)轉(zhuǎn)義的&字符&,那么輸出的 html 文件中也會(huì)有一個(gè)&,而不單單是一個(gè)字符&。如果你再仔細(xì)想一想,你會(huì)發(fā)現(xiàn)這種情況會(huì)導(dǎo)致很多問題。例如,假設(shè)一個(gè)聚合文件的標(biāo)題是“Matt''s <i>Cool</i> Blog”,如果輸出轉(zhuǎn)義沒有被禁止,那么輸出就會(huì)保留 “Matt''s <i>Cool</i> Blog”,在 Web 頁(yè)面就會(huì)顯示為 "Matt''s <i>Cool</i> Blog"。當(dāng)用 disable-output-escaping="yes"設(shè)置禁止輸出轉(zhuǎn)義時(shí),輸出就不會(huì)被轉(zhuǎn)義,上面的內(nèi)容就會(huì)被當(dāng)作“Matt''s <i>Cool</i> Blog”,顯示在頁(yè)面上就是我們想要的“Matt''s Cool Blog”。

  另一個(gè)要注意的是元素<a>。這個(gè)奇怪的語法會(huì)生成下面的輸出內(nèi)容:

<a href="DisplayItem.aspx?ID=position">news item title</a>

  之所以要使用這種語法,是因?yàn)橐o XSLT 樣式表中某個(gè)你要?jiǎng)?chuàng)建的元素添加一個(gè)屬性,然后在該元素的標(biāo)簽里使用 <xsl:attribute> 語法 。有關(guān)該語法的一些例子可在 W3Schools 網(wǎng)站上找到:The <xsl:attribute> Element。

  最后要注意的是,超鏈接的ID查詢字符串的值是來自于 <xsl:number> 元素,從 position() 函數(shù)中返回的值。<xsl:number> 元素僅僅是輸出一個(gè)數(shù)值。position()函數(shù)是一個(gè) XPath 函數(shù),用來返回 XML 文檔中當(dāng)前節(jié)點(diǎn)的順序位置。這意味著對(duì)于第一個(gè)新聞項(xiàng),position() 函數(shù)返回 1,第二個(gè) 新聞項(xiàng),position函數(shù)返回 2,以此類推。我們需要記錄這個(gè)值并將它通過查詢字符串傳遞出去。這樣當(dāng) DisplayItem.asp 頁(yè)面被訪問時(shí),就可以知道顯示 RSS 聚合摘要的什么項(xiàng)目了。

  聰明的讀者可能已經(jīng)注意到,我們的 XSLT 樣式表沒有全部完成,因?yàn)?nbsp;FeedID 參數(shù)沒有通過查詢字符串傳遞到 DisplayItem.aspx 頁(yè)面。要明白 這是為什么,我們回顧一下在 ID 查詢串參數(shù)中所傳遞的是用戶擬察看詳細(xì)信息的<item>元素順序號(hào)。也就是說,如果用戶點(diǎn)擊第四條新聞項(xiàng),頁(yè)面 DisplayItem.aspx?ID=4 就會(huì)被 加載到右下部分的框架中。問題在于 DisplayItem.aspx 頁(yè)面無法確定用戶希望查看哪一個(gè)摘要。有兩個(gè)不同的方法可以解決這個(gè)問題,比如可以在右下部框架中用客戶端 Javascript 代碼讀取右上部框架的 URL,然后確定FeedID 的值。在我看來,更簡(jiǎn)單的辦法是和 ID 參數(shù)一起將 FeedID 的值通過查詢字符串傳遞 。

  這樣的話,有一個(gè)難題是 XSLT 樣式表操縱的 RSS XML 數(shù)據(jù)中并沒有 FeedID 值。但是 DisplayNewsItems.aspx 頁(yè)面知道 FeedID 值,需要一種方法讓 XSLT 樣式表也知道這個(gè)值。通過使用 XSLT參數(shù)可以 實(shí)現(xiàn)完成。

   XSLT 參數(shù)的使用是非常簡(jiǎn)單。在 XSLT 樣式表中,你需要在 <xsl:template> 元素中加入一個(gè)<xsl:param> 元素, 該元素提供參數(shù)的名稱。下面的代碼將這個(gè)參數(shù)命名為 FeedID:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/rss/channel">
<xsl:param name="FeedID" />

...
</xsl:template>
</xsl:stylesheet>

  現(xiàn)在,就可以用下面的語法在<xsl:value-of>元素中使用這個(gè)參數(shù)了:

<xsl:value-of select="$parameterName" /> 

  最后,在我們的 XSLT 樣式表中加入下面的代碼,我們就可以把 FeedID 查詢字符串參數(shù)加到超鏈接中了:

<a>
<xsl:attribute name="href">DisplayItem.aspx?ID=<xsl:number 
value="position()" />&FeedID=<xsl:value-of select="$FeedID" 
/></xsl:attribute>

  注意在ID查詢字符串參數(shù)后面我們加了一個(gè)&字符(轉(zhuǎn)義&),這樣我們就可以傳遞 FeedID 參數(shù)的值到查詢字符串的 FeedID 參數(shù)中了。 這就是我們要在 XSLT 樣式表中添加的內(nèi)容。

  剩下的工作是在 DisplayNewsItems.aspx 頁(yè)面的 Page_Load 事件處理函數(shù)中設(shè)置這個(gè)參數(shù)的值。通過使用 XsltArgumentList 類可以完成這一工作。這個(gè)類有一個(gè) AddParameter() 方法。一旦我們創(chuàng)建了這個(gè)類的一個(gè)實(shí)例,加入了相應(yīng)的參數(shù),就可以將這個(gè) 實(shí)例賦給 XML Web 控件的 TransformArgumentList 參數(shù)了。下面的代碼顯示了更新后的 DisplayNewsItems.aspx 頁(yè)面 Page_Load 事件處理函數(shù):

顯示特定新聞項(xiàng)的詳細(xì)內(nèi)容 

  還剩下最后一件需要做的事情是顯示用戶選擇的特定新聞項(xiàng)的詳細(xì)內(nèi)容。這些詳細(xì)內(nèi)容將顯示在右下部的框架中,而且將會(huì)顯示新聞項(xiàng)的標(biāo)題,描述和新聞項(xiàng)的鏈接等信息。和 DisplayNewsItem.aspx 頁(yè)面 類似,DisplayItem.aspx 頁(yè)面首先將根據(jù)傳入的 FeedID 查詢字符串參數(shù)獲取遠(yuǎn)程的 RSS 聚合摘要,然后它會(huì)用 XML Web 控件顯示這些詳細(xì)內(nèi)容。實(shí)際上,DisplayItem.aspx 頁(yè)面的 Page_Load 事件處理函數(shù)和DisplayNewsItem.aspx 頁(yè)面的 該函數(shù)幾乎一樣,只有以下兩個(gè)小小的區(qū)別: 

DisplayItem.aspx 頁(yè)面需要讀取ID查詢字符串參數(shù)的值;
DisplayItem.aspx 頁(yè)面使用一個(gè) XSLT 參數(shù),但是這個(gè)參數(shù)與 DisplayNewsItem.aspx 頁(yè)面用的參數(shù)是不一樣的; 
DisplayNewsItem.aspx 和 DisplayItem.aspx 頁(yè)面一樣都需要在參數(shù)中傳遞一個(gè) XSLT 樣式表。DisplayNewsItem.aspx 頁(yè)面?zhèn)鬟f的是 參數(shù) FeedID,而 DisplayItem.aspx 還需要傳入 ID 參數(shù),它表示 XSLT 樣式表應(yīng)該顯示那個(gè)新聞項(xiàng)。這個(gè)細(xì)小的差別在以下代碼中以粗體顯示,以下 代碼省略了與 DisplayNewsItems.aspx 頁(yè)面相同的部分:

  以下是轉(zhuǎn)換 XML 數(shù)據(jù)的 XSLT 樣式表:

<?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:param name="ID" />

<xsl:template match="/rss/channel">
<b><xsl:value-of select="item[$ID]/title" 
disable-output-escaping="yes" /></b>
<p>
<xsl:value-of select="item[$ID]/description" 
disable-output-escaping="yes" />
</p>
<a>
<xsl:attribute name="href"><xsl:value-of 
select="item[$ID]/link" /></xsl:attribute>
<xsl:attribute name="target">_blank</xsl:attribute>
Read More...
</a>
</xsl:template>
</xsl:stylesheet> 

  注意 <xsl:param> 元素被用于聲明 ID XSLT 參數(shù)。然后,在幾個(gè)不同的 <xsl:value-of> 元素中,ID 參數(shù) 被用來從 <item> 元素列表中抓取特定的 <item> 元素。在 XPath 的語法中,elementName[i]意思是根據(jù)相應(yīng)元素名 存取第i個(gè)元素。例如,item[1]將只獲取第一個(gè)<item>元素,item[2]則獲取第二個(gè)元素。所以 item[$ID]是獲取由 XSLT 參數(shù) ID 定義的 特定 <item> 元素。

  最后,值得注意的還有在樣式表靠近末尾部分的超鏈接 Read More…,它的target屬性設(shè)為空,這樣的話當(dāng)用戶點(diǎn)擊 Read More… 鏈接的時(shí)候,瀏覽器會(huì)打開一個(gè)新的窗口。

未來的擴(kuò)展和當(dāng)前程序的缺點(diǎn)

  本文講述的代碼中有一個(gè)明顯的缺點(diǎn)就是每次用戶點(diǎn)擊左邊框架的某個(gè)聚合摘要或者在右上部框架點(diǎn)擊某個(gè)新聞項(xiàng)時(shí),遠(yuǎn)程聚合摘要都會(huì)被裝載和解析。每次用戶點(diǎn)擊遠(yuǎn)程聚合 摘要時(shí),所有的項(xiàng)都被加載,這樣的效率無疑是很差的。每次用戶點(diǎn)擊一個(gè)新聞項(xiàng)標(biāo)題就重新裝載整個(gè)遠(yuǎn)程聚合摘要也是很浪費(fèi)資源的。這樣的方法不僅沒有效率,對(duì)提供發(fā)布服務(wù)的個(gè)人或者公司也是不禮貌的,因?yàn)檫@些 連續(xù)的、不沒必要的請(qǐng)求占用了他們的 Web 服務(wù)器的負(fù)載資源。

  這個(gè)缺點(diǎn)在本文附帶的源代碼中已經(jīng)得到解決。具體來說,.NET數(shù)據(jù)緩存可以用來存放不同摘要的 XmlDocument 對(duì)象。緩存間隔設(shè)置為數(shù)據(jù)表 Feeds 中 UpdateInterval 字段定義的值。(當(dāng)然,由于某些原因,摘要的 XmlDocument 對(duì)象有可能會(huì)被提前清除出緩存)
  這個(gè)系統(tǒng)的另外一個(gè)缺點(diǎn)是在右上部框架和右下部框架之間沒有狀態(tài)的保存。為了說明這樣會(huì)引起什么問題,考慮以下的動(dòng)作: 

  用戶點(diǎn)擊左邊框架的某個(gè)聚合摘要鏈接,在右上部框架中裝載這個(gè)摘要的新聞項(xiàng)目。假設(shè)這個(gè)摘要的UpdateInterval 的值是30,則表示這些內(nèi)容在30分鐘之 后會(huì)過期;
  裝載右上部框架的新聞項(xiàng)的同時(shí),這些內(nèi)容被緩存起來;
  用戶離開去吃午飯;
  發(fā)布聚合內(nèi)容的網(wǎng)站增加了一條新的新聞項(xiàng);
  我們的用戶一個(gè)小時(shí)午飯后回來了,這個(gè) 摘要的 XmlDocument 的緩存已經(jīng)過期; 
  用戶點(diǎn)擊右上部框架的第一條新聞項(xiàng),將會(huì)在右下部分框架中裝載 DisplayItem.aspx,傳入 ID 參數(shù)值1; 
  DisplayItem.aspx 頁(yè)面在緩存中沒找到 XmlDocument 對(duì)象,只好重新獲取遠(yuǎn)程摘要。這樣就會(huì)獲得新的數(shù)據(jù)了(別忘了,步驟 4 已經(jīng)加了一個(gè)新的新聞項(xiàng)),然后此頁(yè)面會(huì)顯示第一條新聞項(xiàng)目(因?yàn)镮D參數(shù)的值為1) ; 
  用戶看到了新的新聞項(xiàng),但是內(nèi)容會(huì)令他感到有點(diǎn)困惑,因?yàn)橐呀?jīng)不是他所點(diǎn)擊的那一條新聞了,而且右上部也沒有顯示那條新的新聞。 

  之所以出現(xiàn)這樣的問題,是因?yàn)?nbsp;ID 參數(shù)沒有唯一地標(biāo)識(shí)一個(gè)新聞項(xiàng),它只是一個(gè)特定時(shí)間點(diǎn)上新聞項(xiàng)列表中的一個(gè)偏移量。解決這個(gè)問題的一個(gè)好的方法是不要用數(shù)據(jù)緩存來保存聚合 摘要,而是使用數(shù)據(jù)庫(kù)或者持久介質(zhì)的其它方式(比如 Web 服務(wù)器本地文件系統(tǒng)的 XML 文件)。如果使用數(shù)據(jù)庫(kù),每一個(gè)新聞項(xiàng)都可以擁有一個(gè)唯一的標(biāo)識(shí)號(hào),可以用來傳遞到右下角的框架中。這種方法可以保證解決上面提到的問題。當(dāng)然也會(huì)增加系統(tǒng)的復(fù)雜性,比如需要決定何時(shí)從數(shù)據(jù)庫(kù)中清除掉舊的新聞項(xiàng) 。

  本文現(xiàn)有的應(yīng)用程序還缺少異常處理,而這肯定是應(yīng)該加上的。尤其是當(dāng)從遠(yuǎn)程 RSS 聚合摘要文件獲取數(shù)據(jù)并加載到 XmlDocument 對(duì)象時(shí),應(yīng)該加上異常處理。因?yàn)檫h(yuǎn)程的文件可能不存在或者格式不正確。

  還有很多增強(qiáng)功能可以輕松地加入到這個(gè)在線新聞聚合器。一個(gè)明顯的功能是需要一個(gè)管理頁(yè)面來允許用戶添加,刪除和編輯他們現(xiàn)在的聚合摘要。還有,如果能允許用戶自定義分類 ,將他們的聚合摘要按類別放在一起就更好了。另外,現(xiàn)在的用戶界面還是比較粗糙的,但是通過增加一些 XSLT 樣式表生成的 HTML 代碼或者在幾個(gè)框架里面增加一些樣式表就可以很容易地美化一下界面。最后,在html標(biāo)簽里面加一些<meta>元素,可以讓右上部框架定時(shí)地去刷新,使得用戶不用自己手工去刷新頁(yè)面就可以看到最新的新聞項(xiàng)目。

  注解 (2003年8月4日): 在這篇文章發(fā)布以后,一些讀者用 Email 告訴通知我在顯示特定 RSS 聚合項(xiàng)的 <description> 元素時(shí),有兩個(gè)潛在的問題:
  1、Disable-output-encoding 屬性,這個(gè)屬性用在 <xsl:value-of> 元素中,但是并不是所有的 XSLT解析器都實(shí)現(xiàn)了這個(gè)功能。.NET XSLT 解析器支持 disable-output-encoding,但是還是要 注意一下,因?yàn)樽x者可能試圖將這個(gè)應(yīng)用程序移植到其它平臺(tái)。
  2、<description> 元素的 HTML 內(nèi)容是被原封不動(dòng)地輸出的。但是,這些 HTML 內(nèi)容可能包含惡意代碼,比如 <script> 或者 <embed> 代碼塊。理想情況下,這些代碼應(yīng)該被剔除掉。為了清除掉這些有潛在危險(xiǎn)的代碼,可能需要用到一些擴(kuò)展函數(shù)(參見 Extending XSLT with JScript, C#, and Visual Basic .NET)。想查看從 RSS 聚合 摘要剔除 HTML 內(nèi)容的更多信息,可以參見''Dive Into Mark'' 日志。

總結(jié) 

  在本文中,我們不僅講到如何創(chuàng)建一個(gè)聚合引擎,還創(chuàng)建了一個(gè)在線新聞聚合器。在建立這兩個(gè)應(yīng)用程序時(shí),我們都采用了在 ASP.NET 頁(yè)面顯示 XML 數(shù)據(jù)的技術(shù)。在聚合引擎里面,我們使用了 Repeater 控件以 XML格式來顯示數(shù)據(jù)庫(kù)中的數(shù)據(jù)。而在新聞聚合器里面,我們使用了 XML Web 控件和 XSLT 樣式表。

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

用 Asp.Net 建立一個(gè)在線 RSS 新聞聚合器的方法

用 Asp.Net 建立一個(gè)在線 RSS 新聞聚合器的方法:隨著辦公室和家庭上網(wǎng)在線時(shí)間的延長(zhǎng),以及 Web 站點(diǎn)和可訪問的互聯(lián)網(wǎng)應(yīng)用程序呈持續(xù)爆炸性增長(zhǎng),應(yīng)用程序之間能數(shù)據(jù)共享變得越來越重要。在異構(gòu)平臺(tái)之間共享數(shù)據(jù)需要一種平臺(tái)中立的數(shù)據(jù)格式,這種數(shù)據(jù)格式要求能易于通過標(biāo)準(zhǔn)的互聯(lián)網(wǎng)協(xié)議來傳輸,而這正是X
推薦度:
  • 熱門焦點(diǎn)

最新推薦

猜你喜歡

熱門推薦

專題
Top