|
層級: 初級 Benoît Marchal (bmarchal@pineapplesoft.com), 顧問, Pineapplesoft 2006 年 11 月 27 日
Web 網站上的 RSS 和 Atom 提要如同雨後春筍般湧現。它們之所以如此流行,原因就在於為忠誠的訪問者提供了一種簡單的機制,協助他們註冊網站、獲得更新通知。但對於使用者來說,它們並非總是非常簡單,特別是那些使用較舊的瀏覽器的使用者更是如此。在這篇文章中,Benoît 介紹了一種技術,協助 Web 網站的訪問者閱讀和理解 RSS 和 Atom 提要。
迎合更多的受眾 RSS 和 Atom 提要提供了一種極其有效解決方案,使訪問者可以訂閱您的網站,並在新項目可用時得到通知。它們的流行程度與日俱增,原因在於訪問者越來越多地關注自己的隱私、警惕垃圾郵件。Atom 和 RSS 使訪問者能夠獲得您的網站的最新資訊,並且無需提供任何私人資料。 RSS 在 blog 中非常流行,但它並非局限於 blog:所有網站都能夠從建立起忠實的客戶關係中受益。 Web 網站管理員所面臨的挑戰之一就是 RSS 和 Atom 依然屬於新興事物,知道它們的人並不多,瞭解其用法並安裝了恰當的軟體的人更是少之又少。 這一挑戰特別困難之處就在於您必須在 Web 網站上放置一個 RSS 或 Atom 檔案的連結,以便訪問者訂閱,但若單擊此連結,許多訪問者都會看到 XML 代碼,看起來顯然不是非常友好。 Web 連鎖(Web syndication)正處於過渡階段。它已經體現出自己的優勢,值得在您的 Web 網站中構建 RSS,但依然有許多使用者尚未完成恰當的配備,無法訂閱 RSS 提要。Apple Safari 是第一個帶有內建 RSS 支援的主流瀏覽器(2005 年)。Firefox(v 1.5)、Internet Explorer(v 7)和 Opera(v 9)很快跟進。 到了明年這個時候,所有主流瀏覽器都將提供極好的 RSS 支援。可能還要再過一兩年,大多數使用者才會升級完成,在那之前,您無法放心地假設所有訪問者都使用支援 RSS 的瀏覽器。 在此期間,您可提供一種幾乎能與所有瀏覽器正常配合的替代性選擇。 既然 RSS 是 XML,就按 XML 的方式處理它! 情況究竟怎樣?RSS 或 Atom 提要是一種 XML 文檔。使用者單擊它時,瀏覽器下載文檔,並試圖將其作為 XML 顯示,也就是原始代碼。更糟糕的是,某些版本的 Internet Explorer 將顯示安全警告。 這種情況並不輕鬆。從技術上來說,RSS 提要應具有 application/rss+xml MIME 類型,而 Atom 提要應標識為 application/atom+xml。如果 MIME 類型正確,訪問者的機器上也正確地安裝了新聞彙總器(news aggregator),瀏覽器將自動啟動它。 在實踐中,很少有訪問者具有恰當的配置,他們很可能會看到晦澀的錯誤訊息。因此,大多數 Web 網站都使用 text/xml or application/xml MIME 類型,這是不正確的,但至少使瀏覽器能夠顯示出原始 XML 代碼。這隻是比錯誤訊息有些許改進,但仍然像是在告訴使用者:嘿!能理解多少就是多少吧。 更糟糕的是,由於配置錯誤,某些網站將 XML 文檔作為 application/octet-stream 提供。Web 管理員必須補救伺服器配置,以使用最恰當的 MIME 類型。例如,對於流行的 Apache Web 服務器,這是在 .htaccess 檔案中完成的。 為緩解問題,最新的瀏覽器會嗅探(sniff) 傳入的 XML 檔案,以恰當地對其加以分類。簡單地說,嗅探就表示它們將讀取開頭的一些位元組,尋找 RSS 或 Atom 標記。但這同樣也要求訪問者使用的是一種支援 RSS 的瀏覽器。 用樣式表來援助 幸運的是,存在一種較好的解決方案:XSLT 樣式表。如果瀏覽器將提要作為 XML 文檔處理,它將使用樣式表來呈現明確的頁面。另一方面,如果瀏覽器識別出 RSS 和 Atom 提要,則將忽略樣式表。瞧!這簡直是世界上最美好的事情! 清單 1 是與一個樣式表關聯的 RSS 文檔(摘自我個人播客的提要)。請注意,第二行是一條 xml-stylesheet 處理指示。這是到樣式表的關鍵連結。href 是樣式表的路徑。 清單 1. RSS 摘錄
<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rssfeed.xsl"?><rss> <channel> <title>Declencheur</title> <link>http://www.declencheur.com/</link> <description>Le podcast qui parle photos.</description> <language>fr</language> <pubDate>Tue, 11 Jul 2006 15:31:46 +0200</pubDate> <item> <title>Cadrage</title> <link>http://www.declencheur.com/clic/archives/2006/07/esposito</link> <description><![CDATA[<p>En 20 minutes, Nicolas nous resume son cours d'esthetique. Il nous livre de nombreuses techniques, astuces et regles d'esthetique pour ameliorer nos photos.</p>]]></description> <pubDate>Mon, 03 Jul 2006 21:30:21 +0200</pubDate> <enclosure length="34812500" type="audio/mpeg" url="http://www.declencheur.com/clic/medias/2006/decl-2006-07-03.mp3"/> </item> <item> <title>Complement visuel : cadrage</title> <link>http://www.declencheur.com/clic/archives/2006/07/esposito-visuel</link> <description> <![CDATA[<p>Le complement visuel de l'episode 6 est maintenant disponible !</p>]]></description> <pubDate>Sat, 01 Jul 2006 12:07:30 +0200</pubDate> <enclosure length="2738765" type="application/pdf" url="http://www.declencheur.com/clic/medias/2006/decl-2006-07-01.pdf"/> </item> </channel></rss> |
清單 2 是樣式表。如果您熟悉 XSLT,那麼在幾分鐘內就可以編寫出一個類似的樣式表……但要注意下一小節中介紹的一個特殊問題。如果您瞭解 XSLT,可直接跳到 下一小節 處。如果還不熟悉 XSLT,請繼續閱讀,我將簡要介紹在本系列其餘部分中處理 RSS 所必需的知識。 清單 2. XSLT 樣式表
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="html"/><xsl:template match="/"> <html> <head> <title><xsl:value-of select="rss/channel/title"/></title> <script type="text/javascript" src="xsl_mop-up.js"/> </head> <body onload="go_decoding();"> <h1><a href="{rss/channel/link}"> <xsl:value-of select="rss/channel/title"/></a></h1> <div id="cometestme" style="display:none;"> <xsl:text disable-output-escaping="yes">&</xsl:text> </div> <p>This is an RSS feed, you must install a news aggregator to subscribe to it. This feed contains the following items:</p> <p><xsl:value-of select="rss/channel/description"/></p> <xsl:for-each select="rss/channel/item"> <h2><a href="{link}"> <xsl:value-of select="title"/></a></h2> <div name="decodeable"> <xsl:value-of select="description" disable-output-escaping="yes"/> </div> <xsl:if test="enclosure"> <p><a href="{enclosure/@url}">Extra...</a></p> </xsl:if> </xsl:for-each> </body> </html></xsl:template></xsl:stylesheet> |
請注意,樣式表是一個 XML 文檔(正像 RSS 或 Atom 流一樣),它使用一個名稱空間(就像 Atom 元素或 RSS 擴充)。通常,對於 XML 文檔,您必須謹慎處理文法。特別是要保證開始標記(<p>)有一個相匹配的結束標記(</p>)。空標記必須遵循特殊的文法(<br />)。 樣式表包含 XSLT 語句以控制呈現(在 http://www.w3.org/1999/XSL/Transform 名稱空間中,清單 2 中的 XSLT 語句以 xsl 首碼開頭),還包含了 HTML 標籤以控制頁面配置。 如果您希望修改 清單 2 以便適應您的網站布局,可以編輯 xsl:template 元素的內容。注意,務必保留 XSLT 語句。 您將需要用到的四條 XSLT 指令是 xsl:value-of、xsl:for-each、xsl:if 和花括弧的使用。 xsl:value-of 指令從 RSS 或 Atom 文檔中提取資訊,並將其插入 HTML。該指令接受一個稱為 select 的屬性和您感興趣的 RSS 或 Atom 元素的路徑。
例如,要複製提要標題,路徑是 rss/channel/title,因為 title 元素出現在 channel 之下,而後者本身又包含在 rss 之中。如您所見,路徑只是按照元素在 RSS 文檔中出現的順序直接列出這些元素。 要從一個屬性中複製資料,可用 @ 作為屬性名稱的首碼,例如 rss/channel/item/enclosure/@url。 xsl:for-each 是迴圈指令。它迴圈遍曆一組元素(也是通過 select 屬性選中的),在本例中是不同的 item。對於每一項,樣式表將輸出基本的資訊:標題、描述和附件連結。
屬性中的花括弧(只用在屬性中)從 RSS 或 Atom 提要中提取資訊,就像 xsl:value-of 從普通文本中提取資訊一樣。在樣式表中,花括弧填充多個 href 屬性。 最後但並非最不重要的一條指令就是 xsl:if,它只在其測試成功的情況下才會執行。在 清單 2 中,xsl:if 測試是否值得輸出附件資訊,或是否缺少附件標記。 這裡只介紹了一些 XSLT 的粗淺內容,但如果您能擅加利用複製粘貼操作和 清單 2,就可以將其調整為適合您的網站的布局。關於 XSLT 的完整教程,請參見 參考資料 部分。 如果您的樣式表未能如願地工作,請按照以下幾方面進行檢查:
- 確保您按照介紹正確地聲明了名稱空間(
xmlns:xsl 屬性),切勿 更改 URI
- 如果您的文檔使用了其他名稱空間(例如 iTunes 擴充),確保您也聲明了這些名稱空間
- 如果樣式表看起來似乎在工作,但您無法提取某些資料,很有可能是路徑問題(在我講授 XSLT 的課程時,我的學生遇到的問題中,有 80% 都是由不正確的路徑導致的)
絕大多數提要編輯器都允許您插入所需的 xml-stylesheet 指令。如果您的提要編輯器不支援它,可改用 FeedBurner 來更新提要。FeedBurner 甚至提供了一個預設的 XSLT 樣式表(請參見 參考資料)。 Firefox 缺陷 如果 Firefox 支援 XSLT 中的 disable-output-escaping 特性,那麼 RSS 和 Atom 世界中將非常美好,但它並不支援。 disable-output-escaping 是 XSLT 中一項不那麼令人信服的特性,它只有一個目的:處理那些出現在其他標記中的標記,例如 CDATA 節。而 RSS 和 Atom 大量使用 CDATA 節以嵌入 HTML 程式碼。
使用 disable-output-escaping,您應能從提要中提取 HTML 標籤,並將其正確地插入到 HTML 頁面中……但 Firefox 未支援這一特性。Firefox 實際上忽略了該指令,最終導致了顯示原始 HTML 程式碼。 對於這種行為是否符合標準,Firefox 社區中一直存在爭論。但這確實是個問題,您需要找到一種解決方案。 幸運的是,Sean M. Burke 提出了一段 JavaScript 代碼,可以巧妙地迴避這種限制。Burke 先生非常友善,公開了自己的代碼,任何人都可以在任何項目中使用這些代碼。方便起見,我在 參考資料 中給出了這段指令碼的連結。 為使該指令碼正常工作,您的樣式表必須插入 div 節,並使用 id “cometestme”。您的樣式表還必須將需要轉義(escape)的所有項目放置在名為 “decodeable” 的段落中。 最後,您必須在載入 HTML 文檔時呼叫指令碼(go_decoding())。 在樣式表中實現什麼功能? 在 RSS 或 Atom 提要中列出項目只是開始。畢竟,Web 網站中已經隨處都有內容,而提要的設計目的在於促進訂閱,而不是複製內容。 流行的解決方案 大多數向 RSS 或 Atom 提要附加了 XSLT 樣式表的 Web 網站管理員都會提供指導資訊,說明如何安裝一個新的彙總器然後訂閱其提要。 雖然這聽起來像是正確合理的作法,但根據我的經驗,看到此類頁面的訪問者未必會去安裝彙總器。在病毒和木馬程式肆虐的網路上,網民們會對安裝軟體的要求充滿猜疑。 因此,許多網站都包含將訪問者定位到線上彙總器(如 Google Reader 或 Yahoo!)的指令。這似乎是個好辦法,但我對這種做法的效率持保留態度。除非訪問者已訂閱了許多提要,否則他們註冊一個新服務的可能性不會比安裝一個新軟體高。假設他們確實註冊了,那麼他們記得去訪問線上彙總器的機會有多大?我的想法是:如果訪問者必須將某個網站加入書籤,那麼我寧願那是我的網站, 別出心裁的想法 從個人角度來說,我提供了一種選擇,利用 RSS 到電子郵件的服務之一通過電子郵件進行訂閱。您可放心地假設,所有訪問者都有一個電子郵件地址。我編寫了詳細的指導說明,列出了選項,並包含了一個非常醒目的電子郵件訂閱表單。我發現,在我個人播客網站中,五分之一的訪問者寧願通過電子郵件訂閱,而不是 RSS。 RSS 和 Atom 可能是較好的技術解決方案,但什麼也比不上一項熟悉的服務,而對於許多訪問者來說,電子郵件就是一種最熟悉的服務。 為了避免重複編寫訂閱指導說明(如果使用多份指導說明,將來有可能出現不一致的風險),我使用了 清單 3 中的樣式表。它比 清單 2 中的要簡單,實現了 HTML 重新導向,將訪問者定位到我的網站內的一個頁面。 清單 3. 最簡單的解決方案?重新導向!
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="html"/> <xsl:template match="rss/channel"><html><head> <title><xsl:value-of select="title"/></title> <meta http-equiv=" refresh" content=" 0; url=http://www.declencheur.com/clic/archives/2006/03/abonnement" /></head><body><h1><xsl:value-of select="title"/></h1><p>Welcome, you are on the RSS feed of <xsl:value-of select="title"/>. The feed offers free subscription services for <xsl:value-of select="title"/>.</p><p>In a moment, you will be redirected to a page with more instructions. <a href="http://www.declencheur.com/clic/archives/2006/03/abonnement"> Click here</a> if the new page fails to open.</p></body></html></xsl:template> </xsl:stylesheet> |
訪問者單擊 RSS 提要時,如果其瀏覽器不能識別 RSS,則將發生重新導向操作! 這篇文章介紹了如何為 RSS 或 Atom 提要打造一張友好的 “面孔”。在它們被廣泛認識之前,將本文介紹的內容作為一項安全措施去實現是個好主意。 |