用ASP.NET建立一個線上RSS新聞彙總器(3)

來源:互聯網
上載者:User
顯示特定彙總摘要的新聞項

  我們面臨的下一個任務是建立 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>

  這個XSLT樣式表只有一個模版,用於匹配“/rss/channel”XPath運算式。這個模版先是以粗體顯示<title>元素的內容。然後,迴圈擷取每一個<item>元素,對於每一個元素,顯示一個到 DisplayItem.aspx 頁面的超連結,在查詢字串中傳遞<item>元素的位置屬性。要留意超連結的 target 屬性設定為 rbottom,右下部架構的名稱。最後,顯示每一個新聞項的標題和<pubDate>元素。

  該 XSLT 樣式表中有兩個項目,並不是每個人都熟悉。首先是 <xsl:value-of> 元素中的 disable-output-escaping="yes" 屬性。從本質上講,這個屬性的設定通知 XSLT 引擎不要轉義那些非法的 XML 字元,比如:&, < , >, " 和 ’’。為了理解這個設定的意義,就要知道,如果不設定該屬性(也就是設定為預設值"no"),那麼如果標題包含一個轉義的&字元&,那麼輸出的 html 檔案中也會有一個&,而不單單是一個字元&。如果你再仔細想一想,你會發現這種情況會導致很多問題。例如,假設一個彙總檔案的標題是“Matt’’s Cool Blog”,如果輸出轉義沒有被禁止,那麼輸出就會保留 “Matt’’s Cool Blog”,在 Web 頁面就會顯示為 "Matt’’s <i>Cool</i> Blog"。當用 disable-output-escaping="yes"設定禁止輸出轉義時,輸出就不會被轉義,上面的內容就會被當作“Matt’’s <i>Cool</i> Blog”,顯示在頁面上就是我們想要的“Matt’’s Cool Blog”。

  另一個要注意的是元素<a>。這個奇怪的文法會產生下面的輸出內容:

<a href="DisplayItem.aspx?ID=position">news item title</a>
  之所以要使用這種文法,是因為要給 XSLT 樣式表中某個你要建立的元素添加一個屬性,然後在該元素的標籤裡使用 <xsl:attribute> 文法 。有關該文法的一些例子可在 W3Schools 網站上找到:The <xsl:attribute> Element。

  最後要注意的是,超連結的ID查詢字串的值是來自於 <xsl:number> 元素,從 position() 函數中返回的值。<xsl:number> 元素僅僅是輸出一個數值。position()函數是一個 XPath 函數,用來返回 XML 文檔中當前節點的順序位置。這意味著對於第一個新聞項,position() 函數返回 1,第二個 新聞項,position函數返回 2,以此類推。我們需要記錄這個值並將它通過查詢字串傳遞出去。這樣當 DisplayItem.asp 頁面被訪問時,就可以知道顯示 RSS 彙總摘要的什麼項目了。

  聰明的讀者可能已經注意到,我們的 XSLT 樣式表沒有全部完成,因為 FeedID 參數沒有通過查詢字串傳遞到 DisplayItem.aspx 頁面。要明白 這是為什麼,我們回顧一下在 ID 查詢串參數中所傳遞的是使用者擬察看詳細資料的<item>元素順序號。也就是說,如果使用者點擊第四條新聞項,頁面 DisplayItem.aspx?ID=4 就會被 載入到右下部分的架構中。問題在於 DisplayItem.aspx 頁面無法確定使用者希望查看哪一個摘要。有兩個不同的方法可以解決這個問題,比如可以在右下部架構中用用戶端 Javascript 代碼讀取右上部架構的 URL,然後確定FeedID 的值。在我看來,更簡單的辦法是和 ID 參數一起將 FeedID 的值通過查詢字串傳遞 。

  這樣的話,有一個難題是 XSLT 樣式表操縱的 RSS XML 資料中並沒有 FeedID 值。但是 DisplayNewsItems.aspx 頁面知道 FeedID 值,需要一種方法讓 XSLT 樣式表也知道這個值。通過使用 XSLT參數可以 實現完成。

   XSLT 參數的使用是非常簡單。在 XSLT 樣式表中,你需要在 <xsl:template> 元素中加入一個<xsl:param> 元素, 該元素提供參數的名稱。下面的代碼將這個參數命名為 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>

  現在,就可以用下面的文法在<xsl:value-of>元素中使用這個參數了:

<xsl:value-of select="$parameterName" />
  最後,在我們的 XSLT 樣式表中加入下面的代碼,我們就可以把 FeedID 查詢字串參數加到超連結中了:

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

  注意在ID查詢字串參數後面我們加了一個&字元(轉義&),這樣我們就可以傳遞 FeedID 參數的值到查詢字串的 FeedID 參數中了。 這就是我們要在 XSLT 樣式表中添加的內容。

  剩下的工作是在 DisplayNewsItems.aspx 頁面的 Page_Load 事件處理函數中設定這個參數的值。通過使用 XsltArgumentList 類可以完成這一工作。這個類有一個 AddParameter() 方法。一旦我們建立了這個類的一個執行個體,加入了相應的參數,就可以將這個 執行個體賦給 XML Web 控制項的 TransformArgumentList 參數了。下面的代碼顯示了更新後的 DisplayNewsItems.aspx 頁面 Page_Load 事件處理函數:

   顯示特定新聞項的詳細內容

  還剩下最後一件需要做的事情是顯示使用者選擇的特定新聞項的詳細內容。這些詳細內容將顯示在右下部的架構中,而且將會顯示新聞項的標題,描述和新聞項的連結等資訊。和 DisplayNewsItem.aspx 頁面 類似,DisplayItem.aspx 頁面首先將根據傳入的 FeedID 查詢字串參數擷取遠端 RSS 彙總摘要,然後它會用 XML Web 控制項顯示這些詳細內容。實際上,DisplayItem.aspx 頁面的 Page_Load 事件處理函數和DisplayNewsItem.aspx 頁面的 該函數幾乎一樣,只有以下兩個小小的區別:

  ·DisplayItem.aspx 頁面需要讀取ID查詢字串參數的值;

  ·DisplayItem.aspx 頁面使用一個 XSLT 參數,但是這個參數與 DisplayNewsItem.aspx 頁面用的參數是不一樣的;

  DisplayNewsItem.aspx 和 DisplayItem.aspx 頁面一樣都需要在參數中傳遞一個 XSLT 樣式表。DisplayNewsItem.aspx 頁面傳遞的是 參數 FeedID,而 DisplayItem.aspx 還需要傳入 ID 參數,它表示 XSLT 樣式表應該顯示那個新聞項。這個細小的差別在以下代碼中以粗體顯示,以下 代碼省略了與 DisplayNewsItems.aspx 頁面相同的部分:

  以下是轉換 XML 資料的 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 參數。然後,在幾個不同的 <xsl:value-of> 元素中,ID 參數 被用來從 <item> 元素列表中抓取特定的 <item> 元素。在 XPath 的文法中,elementName[i]意思是根據相應元素名 存取第i個元素。例如,item[1]將只擷取第一個<item>元素,item[2]則擷取第二個元素。所以 item[$ID]是擷取由 XSLT 參數 ID 定義的 特定 <item> 元素。

  最後,值得注意的還有在樣式表靠近末尾部分的超連結 Read More…,它的target屬性設為空白,這樣的話當使用者點擊 Read More… 連結的時候,瀏覽器會開啟一個新的視窗。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.