RSS從入門到精通

 
1.   令網絡跳動的力量
1.1.RSS
最近在瀏覽許多新聞網站時,用戶都會驚奇的發現一些寫有“XML”字樣的桔黃色圖標頻繁出現。如果使用普通瀏覽器的用戶點擊後只能看到一個寫滿了天書的頁面。這是一種最近十分流行的網絡技術,被稱爲RSS(Really Simple Syndication)。通過專用的RSS閱讀工具,用戶能夠快速瀏覽大量的網頁內容,如新聞或者網絡日誌。最初RSS主要是應用在民間的網絡日誌之中。但由於其易用性迅速受到了歡迎。如今Businessweek、Forbes和New York Times等著名傳統媒體的網站中,也都添加了RSS功能。
使用RSS閱讀工具的用戶可以訂閱自己關注的網站的內容,點擊那個桔黃色的圖標便可以得到RSS種子並且保存到閱讀工具中。RSS閱讀工具會自動連接那些網站檢查並顯示更新內容的標題和摘要內容。
看起來時髦、新奇的RSS技術其實早在1997年左右就已經開發出來,但直到今天才煥發光彩。這其中一個很大的原因是數百萬網絡日誌的出現造成了用戶的閱讀困難。越來越多的公司開始關注RSS技術,除了那些開發RSS閱讀軟件的廠商外,蘋果公司的Safari瀏覽器就內置了RSS閱讀工具。而且微軟也計劃在未來版本的IE瀏覽器中支持RSS閱讀。而另一些RSS服務提供商則支持在線RSS閱讀功能,Bloglines是它們中最有名的傢伙。
1.2.Tag
同RSS技術類似,Tag也是用來對付越來越多的網絡信息的。而它的功能則主要是內容分類。用過Gmail的用戶應該熟悉Tag,在信箱中用戶可以爲每封郵件添加多個關鍵字分類信息,比如工作、廣告、計劃書、已完成等隨心所欲的分類。而檢索時可以按照其中任何一個或者幾個Tag關鍵字進行搜索。這極大豐富了檢索信息的方法和結果的準確性。
例如我曾經在某個網站上看到了一篇關於效力於NBA騎士隊的立陶宛球星伊爾戈斯卡斯講述他家鄉的故事,而當我想再次閱讀這篇文章時卻無法記起這個立陶宛人拗口的名字,而對他的家鄉是哪兒也毫無印象。我如何搜索得到這篇文章呢?Tag就能夠幫助我解決這個問題,當我看到這篇文章的時候,可以把它的鏈接保存在del.icio.us等網絡書籤中,然後爲其添加一個NBA的Tag。這樣日後當我檢索的時候就能夠輕鬆的把它找到。忘掉那些存儲文件夾吧!
Yahoo公司目前十分重視Tag技術,因爲它代表了一種新的組織和管理在線信息的方式。它不同於傳統的、針對文件本身的關鍵字檢索,而是一種模糊化、智能化的分類。這更加符合用戶使用的順滑感和提高檢索結果的相似程度,將會極大的促進用戶查詢數字文件的能力,照片、視頻等多媒體數字文件都可以打上Tag的標籤進行管理。Tag本身絕對無法取代Yahoo和Google這樣的搜索引擎,但如果日後Tag的應用逐漸增長,那麼搜索引擎的使用量一定會減少。
1.3.Wiki
幾乎所有人瞭解Wiki都是從網絡上開放百科全書Wikipedia,開始的,在這之前沒有人見過這樣一個任何人都可以動手修改的網站。從2001年開始,成千上萬名志願者以50種語言完成了這部網絡百科全書中500萬篇文章,這一切都得感謝Wiki!
Wiki一詞來源於夏威夷語的“wee kee wee kee”,原本是“快點快點”的意思。沃德·坎寧安在1995年創建了Wiki的概念和相應的服務系統。這套系統允許那些對編程語言一無所知的人們隨意對一個網站內容進行添加、修改。
而如今有軟件開發商根據Wiki的理論和機制開發出了協同工作軟件。IBM公司的Lotus Notes就屬於同類產品。TWiki公司開發的開放源代碼Wiki軟件自2001年至今已有3.5萬人次下載。而這些被下載的程序有2/3用於商業用途,使用者包括迪斯尼、SAP和摩托羅拉這樣聲名赫赫的公司。
2.   什麼是RSS?
也許大家是第一次聽到RSS這個概念,那什麼是RSS呢?RSS是站點用來和其他站點之間共享內容的一種簡易方式(也叫聚合內容),通常被用於新聞和其他按順序排列的網站,例如Blog。
一段項目的介紹可能包含新聞的全部介紹等。或者僅僅是額外的內容或者簡短的介紹。這些項目的鏈接通常都能鏈接到全部的內容。網絡用戶可以在客戶端藉助於支持RSS的新聞聚合工具軟件,在不打開網站內容頁面的情況下閱讀支持RSS輸出的網站內容。
說得更加簡單一點,RSS就是一種用來分發和彙集網頁內容的XML格式!如果你還是不太明白,沒有關係,RSS是什麼其實基本就不重要,重要的是RSS可以做什麼,下面我們就來了解一下,RSS能給我們帶來什麼?
2.1.小知識
  BLOG:BLOG是Web Log的簡稱。在國內,人們通常稱它爲博客。它是一種作者與讀者以日記風格進行交互的中介。在軟件社區,人們以博客形式來共享觀念與思想變得越來越流行,人們開始以博客的形式互相學習,博客已經成了一個技術交流的場所!如:http://blogs.msdn.com 就是MSDN上的一個blogging。而在國內博客中國也已經越來越有名。http://www.blogchina.com
  XML:XML是Extensible Markup Language的簡寫,一種擴展性標識語言。
3.   可以幹什麼?RSS
1.       訂閱BLOG(BLOG上,你可以訂閱你工作中所需的技術文章;也可以訂閱與你有共同愛好的作者的日誌,總之,BLOG上你對什麼感興趣你就可以訂什麼)。
2.       訂閱新聞(無論是奇聞怪事、明星消息、體壇風雲,只要你想知道的,都可以訂閱)。
你再也不用一個網站一個網站,一個網頁一個網頁去逛了。只要這將你需要的內容訂閱在一個RSS閱讀器中,這些內容就會自動出現你的閱讀器裏,你也不必爲了一個急切想知道的消息而不斷的刷新網頁,因爲一旦有了更新,RSS閱讀器就會自己通知你!
4.   怎樣發佈RSS內容
首先你需要理解一點支持RSS的技術。
1.RSS是包含你要發佈的信息(標題、簡介、內容等信息)的標準的XML文件。它遵循所謂的RSS技術規範定義的格式。
2.RSS文件本身定義的是內容,並沒有定義內容的顯示方式。通常要通過RSS閱讀器來解析內容,並顯示出來。看天下RSS閱讀器就是用來解讀RSS內容的。
3.由於Blog等的發展,使得創建RSS文件變得很容易。
怎樣讓更多的人接收到你的RSS?到目前爲止,大多數人並不對RSS很熟悉。但由於RSS避免了無用的廣告和垃圾信息,這種方式在逐漸地普及開來。
那麼你在採用RSS的時候,就應該儘可能地給你的用戶講解什麼是RSS,以及它有哪些優點。
5.   RSS閱讀器
目前,RSS閱讀器基本可以分爲兩類。
第一類大多數閱讀器是運行在計算機桌面上的單機應用程序,通過所訂閱網站和博客(blog)中的新聞供應,可自動、定時地更新新聞標題。在該類閱讀器中,有Awasu、FeedDemon和RSSReader這三款流行的單機版閱讀器都提供免費試用版和付費高級版,另外,新華網在不久前也推出了一款RSS閱讀器,它不僅是完全是中文界面,而且目前還是完全的免費軟件!(後面我們就將以這款軟件爲例,爲大家介紹怎樣來使用RSS閱讀器)。
第二類新聞閱讀器通常是內嵌於已在計算機中運行的應用程序中。例如,NewsGator內嵌在微軟的Outlook中,所訂閱的新聞標題位於Outlook的收件箱文件夾中。另外,Pluck內嵌在Internet Explorer瀏覽器中!
6.   推” 技術遠勝於電子郵件的推廣模式RSS“
幾乎每一個內容提供者都有過用一個長長的電子郵件地址簿發佈新信息的經驗。RSS“推”技術將從此改變這個現狀。利用RSS閱讀器接收“推”來的新信息不僅消除了“垃圾郵件”充斥郵箱的煩惱,而且使內容接收者更方便地閱讀和管理信息。因此,儘管利用電子郵件的推廣方式還將在很長時間內存在,用戶將越來越偏好使用RSS“推” 技術的內容提供商。
RSS優於電子郵件還體現在網絡安全上。由於沒有不速之客的“垃圾郵件”,也沒有郵件提供商(象YAHOO,MSN)的“強力過濾”,用戶將有十分的信心他們看到的就是他們訂閱的,不多也不少。
不僅如此,即使到達用戶信箱中的合法推廣信息也還有一大部分由於與少數“漏網”的垃圾郵件和衆多其它郵件的混合而被用戶忽視甚至直接刪除。更不用說當用戶因爲信箱裝滿了垃圾而轉用新地址時,絕大多數情況下是想不起來在所有內容提供者那裏更新地址的。這些無疑都是對內容提供者來說巨大的浪費!
我的朋友們有很多是網上內容發佈者,他們都發現新用戶註冊後不出幾個月,這些郵件地址就失效了,而他們也就永遠失去了和這些用戶聯絡的渠道。所以,我建議所有內容提供者都認真地考慮利用RSS“推” 技術來與用戶建立持久穩定的關係,這在長期來講是絕對有利的。
最後,RSS優於電子郵件還在於目前的一些RSS內容聚合商(如看天下www.kantianxia.com)幫助支持RSS“推”技術的內容提供者向用戶作宣傳。如看天下的“RSS內容源索引”就是一個使用戶發現並接受新內容源的增值平臺 - 這與搜索引擎把內容聚合起來向用戶作推廣是一個概念。
目前,越來越多的用戶已經開始認識並接受RSS技術。我衷心希望所有的內容提供者都能順應這個潮流,在這個新的平臺上取得更好的成績。
7.   認識RSS
以下內容是爲了讓大家更加了解RSS,如果你對其不感興趣,完全可以不看,它不會對你使用RSS閱讀產生多大的影響。
7.1.Feed(提要)
博客以RSS文檔形式爲其內容提供一個提要,該RSS文檔可以通過衆所周知的URL獲得。RSS文檔是一個XML文件,它包含大量離散的新聞項,如某個博客中的入口項。由於RSS是XML格式文件,所以它很容易被其它程序所使用。
RSS聚合器是一個讀取RSS文檔並顯示新聞項的程序。大多數聚合器只要輸入RSS的URL,使得預定提要成爲可能。
RSS使閱讀博客便得容易。大多數經常閱讀博客的開發人員都使用某種類型的聚合器來幫助他們有效地篩選提要內容。聚合器使得閱讀博客的感覺就象是在閱讀電子郵件,因爲它們突出新聞項並將新聞項進行緩衝處理以便離線閱讀。
還有一些在線RSS聚合器將RSS提要捆綁到某個單獨的網站。其優點是易於設置並且可以從任何計算機存取你的提要內容。當然,其缺點也是顯而易見的,那就是在閱讀時必須始終保持連接。
RSS是博客成爲一種強大的新型信息交流形式之根本所在。在網誌出現之前,大多數開發人員爲了要查找到需要的內容,通常要花大量時間來篩選掉那些令人討厭的無關的信息。
博客通過讓讀者選擇所要閱讀的提要,將控制權交給讀者,從而有效地構建自己的個性化內容流。
7.2.RSS版本
RSS的版本有很多個,0.90、0.91、0.92、0.93、0.94、1.0 和 2.0。要理解它們需要了解一些有關它們的歷史背景。最初Netscape創建了RSS的最初版本0.90,起初的名字是“RDF Site Summary”或者“Rich Site Summary”(規範中說前者是正式名稱)。Netscape創建RSS0.90用於其Web門戶,這個時候,其他人看到了RSS的使用潛力。Userland Software是第一個開始將 RSS 用於其網誌商業產品者之一。
版本 0.90 在很大程度上基於 W3C 的 Resource Description Framework (RDF)。許多人都認爲 RDF 過於複雜,因此都建議出一個免費的簡化版本 0.91。這個任務恰好就給了 Userland Software。Userland Software 便繼續發展 RSS 的簡化版本,隨後出臺的版本包括:0.92、0.93 和 0.94。爲了強調其所做的簡化工作,他們將 RSS 的全稱定爲“Really Simple Syndication”。
正當Userland Software繼續專注於其簡化工作時,另外一組開發人員在復興最初的RDF版本(0.90),因爲RSS號稱自己更靈活。他們最終發佈了一個RSS 1.0的版本,其正式名稱還是“RDF Site Summary”。由於使用RDF,這個版本完全不同於 Userland Software所控制的版本。Userland Software當然不太願意看到RSS 1.0似乎要取代其0.94版本的事實,於是出了一個新版本,並將版本號一下子跳到了2.0。
這就是今天的這種局面,形成了兩個主要的競爭版本:一個基於RDF1.0,而另一個則是由Userland Software所開發的2.0,由於它們兩個都共用相同的名字。就成爲一種可怕的混亂,因爲版本號導致人們誤認爲2.0是1.0的改進版本,而實際上它們是兩個目標完全不同的規範。現在,另一組開發人員已經下狠心着手解決這種混亂問題,通過定義新的摘要(syndication)規範來與 RSS名字的隨意性決裂。這個解決方案稱爲 Atom(原子)項目。
7.3.Atom(原子)
Atom是一個項目的名字,主要是開發一個新的博客摘要格式以解決目前RSS存在的問題(混亂的版本號,不是一個真正的開放標準,表示方法的不一致,定義貧乏等等)。Atom 希望提供一個清晰的版本以解決每個人的需要,其設計完全不依賴於供貨商,任何人都可以對之進行自由擴展,完整詳細說明。
除了定義新的摘要格式之外,Atom還希望定義一個標準的檔案文件格式和一個標準的博客編輯API(Atom API)。
其實RSS1.0和2.0格式所包含的核心信息是相同的,只是其結構不一樣罷了,這裏我們不再繼續深入的討論這個問題,有興趣的朋友可以去博客中國裏瞭解相關知識!
7.4.blogroll
blogroll是博客頁面提要的集合,大多數博客在其個人頁面上都提供blogroll。這就允許讀者連接到其他趣味和寫作風格相投的人的網頁上。Blogroll方便了網絡上的溝通。通過使用Outline Processor Markup Language(OPML),人們可以用XML 格式文件交換blogroll。
大多數網誌引擎都自己管理blogroll,每當讀者請求blogroll時都自己產生相應的XML格式。同樣,大多數聚合器(RSS閱讀器)都能導入blogroll並自動預定所包含的摘要。
8.   RSS 2.0
8.1.RSS2.0新特性
RSS 2.0 建立在 RSS 0.91 規範的基礎上。它是向後兼容的,因此任何處理 RSS 2.0 的工具應該也能夠處理 0.91 提要。升級後的規範增加了少量元素,比如 <cloud> 和 <guid>。
它也去掉了一些限制。在過去,<link> 和 <url> 元素只能是 http 或 ftp,現在可以使用任何有效的 URI。在 RSS 0.91 中,每個頻道只能包含 15 個項,而且元素的長度也有限制,現在這些限制都取消了。不過仍然應該小心使用較大的值,因爲它們可能對老的應用程序造成問題。
不過更大的變化是能夠使用名稱空間擴展這種格式。RSS 2.0 支持名稱空間,一種增加規範中沒有的元素的標準方法。只要定義在一個名稱空間中,提要可以包含新的元素。
8.2.RSS 2.0 概述
RSS 是一種 XML 方言,用於連鎖 Web 內容和元數據。RSS 0.91 是幾種可用版本中最常用的一種。對於新的 RSS 提要,更好的辦法是使用 2.0 版,因爲這是現行的規範,而且如前所述,它與 0.91 向後兼容。
Dave Winer 編寫了規範的 2.0 版。規範的修改可能變得難以使用,或者損害已有的應用程序,他有意識地避免了這種情況。Winer 總結了他的思想:“保持簡單。這就是 RSS 的價值所在。任何稍微瞭解 HTML 的人都能夠理解 RSS。這一點極其重要!”
該規範在 Creative Commons 許可下發布(請參閱參考資料)。這意味着您可以免費複製和分發該規範,並進行衍生工作,而且可以自由地用於商業工作。一個諮詢委員會負責更新規範、推廣規範和編寫文檔。
8.3.發現 RSS 提要
可以使用搜索引擎查找 RSS 格式的內容。比方說使用 Google 時,您可以在查找中增加“filetype:rss”以搜索 .rss 文件中的查找項。
專門的搜索引擎使內容搜索更加容易。Feedster 監視 weblog 並允許您通過一個日誌項索引查找,按照相關性、日期、等級(logrank)查看。當您在搜索時,Feedster 按照您的要求創建一個 RSS 提要。這個提要可以增加到您的新聞閱讀器中,以便您能夠看到所有與搜索請求有關的最新活動,您甚至不需要離開新聞閱讀器。
DayPop 搜索新聞、blog 和 RSS 提要。它讓您在 weblog 世界跟蹤流行的新聞。它提供了目前最流行的 40 個 weblog 鏈接。這是全世界最流行文章的鏈接。它創建了一個 weblog 中所用最熱門詞彙的列表。它還根據引用對 weblog 評級,提供最受其他 weblogger 歡迎的 weblog 列表。您也可以自定義搜索。評級列表和自定義搜索都有 RSS 提要形式,可以導入您的新聞閱讀器。
8.4.RSS 文件形式
RSS 文件由一個 <channel> 元素及其子元素組成。除了頻道內容本身之外,<channel> 還以項的形式包含表示頻道元數據的元素 —— 比如 <title>、<link> 和 <description>。項通常是頻道的主要部分,包含經常變化的內容。
8.4.1.    頻道
頻道一般有三個元素,提供關於頻道本身的信息:
<title>:頻道或提要的名稱。
<link>:與該頻道關聯的 Web 站點或者站點區域的 URL。
<description>:簡要介紹該頻道是做什麼的。
許多頻道子元素都是可選的。常用的 <image> 元素包含三個必需的子元素:
<url>:表示該頻道的 GIF、JPEG 或 PNG 圖像的 URL。
<title>:圖象的描述。當頻道以 HTML 呈現時,用作 HTML <image> 標籤的 ALT 屬性。
<link>:站點的 URL。如果頻道以 HTML 呈現,該圖像作爲到這個站點的鏈接。
<image> 還有三個可選的子元素:
<width>:數字,表示圖象的像素寬度,最大值是 188,默認值爲 88。
<height>:數字,表示圖象的像素高度。最大值是 400,默認值爲 31。
<description>:包含文本,在呈現時可以作爲圍繞着該圖像形成的鏈接元素的 title 屬性。
此外還可以使用許多其他可選的頻道元素。多數都是不言自明的:
<language>:en-us
<copyright>:Copyright 2003, James Lewin
<managingEditor>:dan@spam_me.com (Dan Deletekey)
<webMaster>:dan@spam_me.com (Dan Deletekey)
<pubDate>:Sat, 15 Nov 2003 0:00:01 GMT
<lastBuildDate>:Sat, 15 Nov 2003 0:00:01 GMT
<category>:ebusiness
<generator>:Your CMS 2.0
<docs>:http://blogs.law.harvard.edu/tech/rss
<cloud>:允許進程註冊爲“cloud”,頻道更新時通知它,爲 RSS 提要實現了一種輕量級的發佈-訂閱協議。
<ttl>:存活時間 是一個數字,表示提要在刷新之前緩衝的分鐘數。
<rating>:關於該頻道的 PICS 評價。
<textInput>:定義可與頻道一起顯示的輸入框。
<skipHours>:告訴聚集器哪些小時的更新可以忽略。
<skipDays>:告訴聚集器那一天的更新可以忽略。
8.4.2.   
項通常是提要中最重要的部分。每個項都可以關於某個 weblog、完整文檔、電影評論、分類廣告或者任何希望與頻道連鎖的內容的記錄。頻道中的其他元素可能不變,但項經常發生變化。
您可以有任意多個項。以前的規範限值爲 15 個項,如果要保持向後兼容這仍然是一個很好的上限。
8.4.3.    新聞項的元素
每個項通常包含三個元素:
<title>:這是項的名稱,在標準應用中被轉換成 HTML 中的標題。
<link>:這是該項的 URL。title 通常作爲一個鏈接,指向包含在 <link> 元素中的 URL。
<description>:通常作爲 link 中所指向的 URL 的摘要或者補充。
所有的元素都是可選的,但是一個項至少要麼 包含一個 <title>,要麼包含一個 <description>。
項還有其他一些可選的元素:
<author>:作者的 e-mail 地址。
<category>:支持有組織的記錄。
<comments>:關於項的註釋頁的 URL。
<enclosure>:支持和該項有關的媒體對象。
<guid>:唯一與該項聯繫在一起的永久性鏈接。
<pubDate>:該項是什麼時候發佈的。
<source>:該項來自哪個 RSS 頻道,當把項聚合在一起時非常有用。
清單 1 是一個 RSS 2.0 文件的例子。注意,頻道包含在 <rss version="2.0"> 中。這是一個非常基本的例子,說明了項和圖像如何包含在頻道中。所示的元素都是最常用的頻道子元素。
清單 1. 示例 RSS 2.0 文件
<?xml version="1.0"?>
<rss version="2.0">
   <channel>
   <title>The channel's name goes here</title>
   <link>http://www.urlofthechannel.com/</link>
   <description>This channel is an example channel for an article.
   </description>
   <language>en-us</language>
   <image>
     <title>The image title goes here</title>
     <url>http://www.urlofthechannel.com/images/logo.gif</url>
     <link>http://www.urlofthechannel.com/</link>
   </image>
   <item>
     <title>The Future of content</title>
     <link>http://www.itworld.com/nl/ecom_in_act/11122003/</link>
     <description> The issue of people distributing and reusing
     digital media is a problem for many businesses. It may also be
     a hidden opportunity. Just as open source licensing has opened
     up new possibilities in the world of technology, it promises to do
     the same in the area of creative content.</description>
   </item>
   <item>
     <title>Online Music Services - Better than free?</title>
     <link>http://www.itworld.com/nl/ecom_in_act/08202003/</link>
     <description>More people than ever are downloading music from
     the Internet. Many use person-to-person file sharing programs like
     Kazaa to share and download music in MP3 format, paying nothing.
     This has made it difficult for companies to setup online music
     businesses. How can companies compete against free?</description>
   </item>
 </channel>
</rss>
8.5.相關工具
由於 RSS 的普及,出現了許多工具,使您能夠基本上在任何環境中使用這些文件:
Java 技術:可在 Sun 站點上找到的一個 RSS Utilities Package,支持在 JavaServer Pages 中使用 Tag Library。它還包括一個 RSS 解析器。
Perl:已經有幾種 Perl 工具處理 RSS。XML::RSS 提供了創建和維護 RSS 文件的一個框架。它支持在常用版本之間的轉換。
Python:RSS.py 是一組通過 Python 使用 RSS 頻道的類。
此外,許多內容管理和 weblog 工具也直接支持 RSS。多數 weblog 工具,包括 Movable Type、Blogger 和 Radio Userland 都支持 RSS。一些內容管理系統,包括 Zope 和 CityDesk 現在也支持它了。
8.6.擴展 RSS
RSS 2.0 有許多可選元素,包括多數頻道都需要的那些元素。但是它還支持擴展性,因此您可以使用規範中沒有的元素。不過,RSS 2.0 規範並沒有花費多少時間定義如何實現擴展。關於擴展性,規範中總結爲:“RSS 提要可以包含本頁中沒有描述的元素,只要這些元素定義在一個名稱空間中。”
這就留下了很大的想像空間!所幸的是,規範中包含一個例子,您可以參考目前使用的幾個例子。
基本的思想是您可以增加需要的標籤 —— 但是,增加帶有多種含義的元素太容易了。使用您的頻道的人們可能並不知道某個標籤是什麼含義。比如,如果我要在一個頻道中使用 <analog> 標籤,它的含義就不很清楚。Web 專家可能認爲這個標籤指的是 Analog,它是最流行的 Web log 文件分析器。科幻迷可能認爲這個標籤是關於 Analog 的,一本經典的科幻雜誌。音樂家可能認爲它指的是流行的合成器類型,生物學家認爲這是一種器官,電子工程師認爲是一種電路。含糊性使人們很難理解標籤的含義。
因此,RSS 允許您增加所喜歡的任何標籤,但是要求必須和名稱空間一起使用。這樣有助於澄清標籤的含義。
再回到 <analog> 的例子,我可能希望創建一組關於電子商務的標籤,並讓 <analog> 標籤作爲一個“e-business”元素。爲此,我增加如下的名稱空間:
xmlns:ebusiness="http://www.lewingroup.com/ebusinessChannel"
這就創建了一個名爲“ebusiness”的名稱空間,並表明這個名稱空間的文檔在我的站點上。爲了使用 <analog> 標籤,我可以使用這種格式:<ebusiness:analog>。這樣就能與其他類似的含義中區分開來,比如 <sciencefiction:analog> 或 <synthesizers:analog>。
關於擴展性,一個更實際的例子可以在 RSS 2.0 規範的示例文件中找到:
清單 2. RSS 2.0 規範示例文件中的名稱空間
<?xml version="1.0"?>
<!-- RSS generated by Radio UserLand v8.0.5 on 9/30/2002; 4:00:00 AM Pacific -->
<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">
 <channel>
   <title>Scripting News</title>
   <link>http://www.scripting.com/</link>
   <description>A weblog about scripting and stuff like that.</description>
   <language>en-us</language>
   <blogChannel:blogRoll>
     http://radio.weblogs.com/0001015/userland/scriptingNewsLeftLinks.opml
   </blogChannel:blogRoll>
     <item>
     <description>Joshua Allen:
     <a href="http://www.netcrucible.com/blog/2002/09/29.html#a243">
     Who loves namespaces?</a></description>
     <pubDate>Sun, 29 Sep 2002 19:59:01 GMT</pubDate>
     <guid>
     http://scriptingnews.userland.com/backissues/2002/09/29#When:12:59:01PM
     </guid>
     </item>
 </channel>
</rss>
在這個例子中,定義了一個稱爲 blogChannel 的名稱空間。它指向一個文檔,該文檔解釋了幾種常見於 weblog 的新元素的用法。其中之一是 <blogroll>。文檔說明,blogroll 是 weblog 中的一個鏈接集合,指向與您的 weblog 內容相關的站點。
<blogChannel:blogRoll> 標籤提供了用戶或軟件所需要的信息,知道 blogRoll 是一個定義在 blogChannel 名稱空間中的元素,而且可以找到這個文檔的位置。
同樣,RSS 2.0 只對不 屬於規範的元素要求名稱空間。所有的基本標籤都假定在 RSS 2.0 名稱空間中。這使得這種格式更容易使用,因爲除非需要擴展 RSS,否則您完全不需要知道名稱空間。
8.7.RSS2.0標記手冊
注:英文原版請參見http://blogs.law.harvard.edu/tech/rss
RSS是 Really Simple Syndication的縮寫(對rss2.0而言,是這三個詞的縮寫,對rss1.0而言則是RDF Site Summary的縮寫,1.0與2.0走的是兩個體系)
RSS 基於XML,所有的 RSS 必須遵循w3c網站上公佈的XML 1.0 規範。
在一個RSS文檔中,根元素是<rss>,帶有一個必備屬性version,用以指明該文檔遵循的rss規範,如果rss文檔遵循本規範,則version值必須是2.0。
<rss>元素只有一個子元素,包含關於頻道的一些信息。頻道(channel)是整個blog,項(item)指一篇文章或日誌(也有稱這爲post)。
8.7.1.    元素channel的子元素列表RSS2.0
元素(Element)
描述(Description)
值域
重要性
舉例(Example)
title
頻道名稱
 
必備
GoUpstate.com News Headlines
link
頻道的URL
 
必備
http://www.goupstate.com/
Description
頻道的描述
 
必備
The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site.
 
 
 
 
 
language
頻道文章所用語言,
可用netscape或w3c推薦的列表
可選
en-us
copyright
頻道內容的版權說明
 
可選
Copyright 2002, Spartanburg Herald-Journal
managingEditor
責任編輯的email
 
可選
[email protected] (George Matesky)
webMaster
負責頻道技術事務的網站管理員email
 
可選
[email protected] (Betty Guernsey)
pubDate
頻道內容發佈日期,格式遵循RFC822格式(年份可爲2們或4位)
 
可選
Sat, 07 Sep 2002 00:00:01 GMT
lastBuildDate
頻道內容最後的修改日期
 
可選
Sat, 07 Sep 2002 09:42:31 GMT
category
指定頻道所屬的一個或幾個類別
 
可選
<category>Newspapers</category>
generator
生成該頻道的程序名
 
可選
MightyInHouse Content System v2.3
docs
指向該RSS文件所用格式說明的URL
 
可選
http://blogs.law.harvard.edu/tech/rss
cloud
Allows processes to register with a cloud to be notified of updates to the channel, implementing a lightweight publish-subscribe protocol for RSS feeds. More info here.
 
可選
<cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap"/>
ttl
有效期,用以指明該頻道可被緩存的最長時間
分鐘爲單位
可選
<ttl>60</ttl>
image
指定一個 GIF或JPEG或PNG圖片,用以與頻道一起顯示
 
可選
 
rating
這個頻道的分級(主要指成人、限制、兒童等)
 
可選
 
textInput
指定一個text輸入框供用戶輸入,具體信息及功能未定。
 
可選
 
skipHours
提示新聞聚合器,那些小時時段它可以跳過。
 
可選
 
skipDays
提示新聞聚合器,那些天它可以跳過。
 
可選
 
8.7.2.    元素channel的子元素image的子元素列表RSS2.0
元素(Element)
描述(Description)
值域
重要性
舉例(Example)
url
圖片的url
 
必備
 
title
圖片的標題,用於http的alt屬性
 
必備
 
link
網站的url(實際中常以頻道的url代替)
 
必備
 
width
圖片的寬度(象素爲單位)
最大144,默認88
可選
 
height
圖片的高度(象素爲單位)
最大400,默認31
可選
 
description
用於link的title屬性
 
可選
 
8.7.3.    元素channel的子元素cloud的子元素列表RSS2.0
元素(Element)
描述(Description)
值域
重要性
舉例(Example)
domain
Cloud程序所在機器的域名或IP地址
 
 
radio.xmlstoragesystem.com
port
訪問clound程序所通過的端口
 
 
80
path
程序所在路徑(不一定是真實路徑)
 
 
/RPC2
registerProcedure
註冊的可提供的服務或過程
 
 
xmlStorageSystem.rssPleaseNotify
protocol
協議
xml-rpc, soap , http-post 之一
 
xml-rpc
8.7.4.    元素channel的子元素textInput的子元素列表RSS2.0
元素(Element)
描述(Description)
值域
重要性
舉例(Example)
title
Submit按鈕的標籤
 
必備
 
description
解釋text輸入區
 
必備
 
name
Text area對象的名字
 
必備
 
link
處理提交的請求的cgi程序
 
必備
 
8.7.5.    開發RSS2.0接口注意:時間字段必須是rfc 822格式
最早開發WebLucene時:RSS 2.0數據輸出的時間字段是ISO格式:2004-12-25 21:48:09 因此有的RSS解析會出錯。正確的應該是這種格式:
<pubDate>Sun, 26 Dec 2004 21:48:09 +0800</pubDate>
查了一下,原來這種時間格式是:rfc822標準,例如 Thu, 21 Dec 2000 16:01:07 +0200
9.   開發教程RSS
RSS(Really Simple Syndication,真正簡單的連鎖)是一種 Web 內容連鎖格式。RSS 成爲通過 Web 連鎖新聞內容的標準格式。作爲最近與 Sun Microsystems 簽署合同的一部分,我負責開發任何懂得 RSS、JavaServer Pages 和 HTML 的人便可以使用的“JSP 標籤庫”。taglib 主要面向用 RSS 收集新聞內容的 Web 站點的非技術性編輯人員。我的目標是開發在 Web 頁中將簡化使用 RSS 內容(0.91、0.92 和 2.0 版本)的 JSP 標籤庫。
RSS Utilities Package 是該項目的結果。它包括一套自定義 JSP 標籤,這些標籤彌補了 RSS Utilities Tag library 和靈活的 RSS 語法分析器。該文檔說明了如何使用該語法分析器和 RSS Utilities Package 提供的庫。在這裏單擊便可以下載第一個版本。該 zip 文件包含一個 jar 文件 rssutils.jar(該文件包含使用該工具所需的類)和一個 tld 文件(該文件定義從 RSS 文檔中提取信息的 JSP 自定義標籤)。
安裝 taglib
 
儘管使用標籤庫很容易,但在安裝時要求您瞭解 Web 服務器的工作原理和如何去配置它。第一步是下載並解壓包。一旦 zip 文件已經解壓了,在 Web 應用程序的 /WEB-INF/lib 目錄中放置一份 rssutils.jar 和 rsstaglib.tld 的副本。將下面的 taglib 定義添加至 Web 應用程序的 /WEB-INF/web.xml 文件:
<taglib>
<taglib-uri>/WEB-INF/rssutils.tld</taglib-uri>
<taglib-location>/WEB-INF/rssutils.tld</taglib-location>
</taglib>
9.1.使用taglib
一旦 taglib 已經安裝在 Web 應用程序中,按照以下步驟便可以在 JSP 頁面中使用 taglib。首先,將下面一行添加至 JSP 頁面的頂部:
<%@ taglib uri="/WEB-INF/rssutils.tld" prefix="rss" %>
其次,使用 feed 標籤將 RSS feed 添加至 JSP 頁面,如下例所示:
<rss:feed url="http://servlet.java.sun.com/syndication/rss_java_highlights-10.xml" feedId="javaSunCom"/>
"feed" 標籤的 url 屬性必須包含到 RSS 文檔的 URL。"feed" 標籤的 feedId 屬性是任意的,可以設置爲任何值。然而,我們建議該屬性在標識 RSS feed 時要直觀。如果應用程序在防火牆後面,可以使用名爲 proxyAddress 和 proxyPort 的 "feed" 標籤代理屬性來設置代理屬性。如果不知道代理服務器地址代理端口,請與網絡管理員聯繫。下面是一個例子:
<rss:feed url="http://servlet.java.sun.com/syndication/rss_java_highlights-10.xml" feedId="example1" proxyAddress="129.149.246.4" proxyPort="8080"/>
一旦將一個或多個 RSS feed 添加到頁面,您應能使用剩餘的一套標籤來從 feed 中提取幾乎任何信息。下面是一個例子,說明如何提取在上面添加的 RSS feed 頻道的標題:
<rss:channelTitle feedId="javaSunCom"/>
9.2.Taglib 示例
9.2.1.    例 1 (RSS 0.91):
<rss:feed
url="http://servlet.java.sun.com/syndication/rss_java_highlights-XYZCompany-10.xml"
feedId="example1"/>
<b>Image: </b><rss:channelImage feedId="example1" asLink="true"/><br>
<b>Title: </b><rss:channelTitle feedId="example1"/><br>
<b>Link: </b><rss:channelLink feedId="example1" asLink="true"/><br>
<b>Description: </b><rss:channelDescription feedId="example1"/><br>
<ul>
<li><rss:itemTitle feedId="example1" index="0"/><br>
<rss:itemDescription feedId="example1" index="0"/><br><br>
<li><rss:itemTitle feedId="example1" index="1"/><br>
<rss:itemDescription feedId="example1" index="1"/><br>
</ul>
9.2.2.    例 2 (RSS 0.92):
<rss:feed
url="http://static.userland.com/gems/backend/gratefulDead.xml" feedId="example2"/>
<b>Image: </b><rss:channelImage feedId="example2"/><br>
<b>Title: </b><rss:channelTitle feedId="example2"/><br>
<b>Link: </b><rss:channelLink feedId="example2" asLink="true"/><br>
<b>Description: </b><rss:channelDescription feedId="example2"/><br>
<ul>
<rss:forEachItem feedId="example2">
<li><rss:itemDescription feedId="example2"/><br><br>
</rss:forEachItem>
</ul>
9.2.3.    例 3 (RSS 2.0):
<rss:feed
url="http://static.userland.com/gems/backend/rssTwoExample2.xml"
feedId="example3"/>
<b>Image: </b><rss:channelImage feedId="example3"/><br>
<b>Title: </b><rss:channelTitle feedId="example3"/><br>
<b>Link: </b><rss:channelLink feedId="example3" asLink="true"/><br>
<b>Description: </b><rss:channelDescription feedId="example3"/><br>
<b>Copyright: </b><rss:channelCopyright feedId="example3"/><br>
<b>Docs: </b><rss:channelDocs feedId="example3"/><br>
<b>Generator: </b><rss:channelGenerator feedId="example3"/><br>
<b>Language: </b><rss:channelLanguage feedId="example3"/><br>
<b>Last Build Date: </b><rss:channelLastBuildDate
X-Virus: 1
feedId="example3"/><br>
<b>Managing Editor: </b><rss:channelManagingEditor
feedId="example3"/><br>
<b>Pub Date: </b><rss:channelPubDate feedId="example3"/><br>
X-Virus: 1
<b>Skip Days: </b><rss:channelSkipDays feedId="example3"/><br>
<b>Skip Hours: </b><rss:channelSkipHours feedId="example3"/><br>
<b>TTL: </b><rss:channelTTL feedId="example3"/><br>
<ul>
<rss:forEachItem feedId="example3" startIndex="2" endIndex="4">
<li><rss:itemDescription feedId="example3"/><br><br>
</rss:forEachItem>
</ul>
9.3.如何使用 RssParser?
從某種程度上看,語法分析器是該項目的副產品。儘管語法分析器是用標籤庫來開發的,但是它完全是自包含的,它可以在 Java 應用程序中使用。然而,要做到這一點,顯然您至少需要了解如何編寫基本的 Java 代碼。(如果您瞭解如何用 Java 語言編寫 Hello World,就沒什麼問題了。)
首先下載並解壓包。一旦將 rssutils.jar 添加至您的類路徑,就請使用 RssParserFactory 創建 RssParser 接口的實例:
RssParser parser = RssParserFactory.createDefault();
Rss rss = parser.parse(new URL("http://mydomain.com/document.rss"));
語法分析器生成的 RSS 對象是位於提供的 URL 中的 RSS 文檔的 Java 對象表示。使用 RSS 對象提供的方法以獲得其它 RSS 對象的句柄,如 Channels 和 Items。RssParser 也能夠分析 File 對象和 InputStream 對象。
9.4.使用RSSLibJ進行RSS開發
RSS是一個標準的XML文件,Rss閱讀器可以讀取這個XML文件獲得文章的信息,使用戶可以通過Rss閱讀器而非瀏覽器閱讀Blog,我們只要動態生成這個XML文件便可以了。RSSLibJ是一個專門讀取和生成RSS的小巧實用的Java庫,大小僅25k,可以從http://sourceforge.net/projects/rsslibj/下載rsslibj-1_0RC2.jar和它需要的EXMLjar兩個文件,然後複製到web/WEB-INF/lib/下。
使用RSSLibJ異常簡單,我們先設置好HttpServletResponse的Header,然後通過RSSLibJ輸出XML即可:
import com.rsslibj.elements.Channel;
 
public class Writer {
    public static void main(String[] args)
            throws InstantiationException, ClassNotFoundException,
            IllegalAccessException {
        Channel channel=new Channel();
        channel.setDescription("This is my sample channel.");
        channel.setLink("http://localhost/");
        channel.setTitle("My Channel");
        channel.setImage("http://localhost/",
                "The Channel Image",
                "http://localhost/foo.jpg");
        channel.setTextInput("http://localhost/search",
                "Search The Channel Image",
                "The Channel Image",
                "s");
        channel.addItem("http://localhost/item1",
                "The First Item covers details on the first item>",
                "The First Item")
                .setDcContributor("Joseph B. Ottinger");
        channel.addItem("http://localhost/item2",
                "The Second Item covers details on the second item",
                "The Second Item")
                .setDcCreator("Jason Bell");
        System.out.println("The feed in RDF: "+channel.getFeed("rdf"));
    }
}
9.5.JDOM生成RSS方式
package music;
 
 
import org.jdom.*;
import org.jdom.output.*;
import org.jdom.input.*;
import java.io.*;
import java.util.*;
import java.text.DateFormat;
public class RSSCreater
{
    AlbumDto dto=null;
    public RSSCreater(AlbumDto dto,String dir)
    {
        Date date=new Date();
        this.dto=dto;
        String albumName=dto.getAlbumName();
        String artistName=dto.getArtistName();
        DateFormat format=DateFormat.getDateTimeInstance();
        String time=format.format(date);
        int albumId=dto.getAlbumId().intValue();
        String id=String.valueOf(albumId);
        String url="http://localhost:8080/musicWeb/getSongAction.do?categoryId="+id;
        System.out.println("現在時間是:"+time);
        String atitle=artistName+"的新專輯-- "+albumName+"--已經到達本站,歡迎查看";
        try
        {
            String truePath=dir+"/"+"index.xml";
            SAXBuilder sb = new SAXBuilder();
            Document doc = sb.build(new FileInputStream(truePath));
            Element root = doc.getRootElement();
            java.util.List books = root.getChildren("channel");
            Element item=(Element)books.get(0);
 
            Element it=new Element("item");
            Element title=new Element("title").setText(atitle);
            Element lint=new Element("link").setText(url);
            Element datetime=new Element("pubDate").setText(time);
            Element guid=new Element("guid").setText(url);
 
            it.addContent(title);
            it.addContent(lint);
            it.addContent(guid);
            it.addContent(datetime);
            item.addContent(it);
 
             File files=new File(truePath);
            Writer xmlwriter=new FileWriter(files);
            FileOutputStream outstream=new FileOutputStream(files);
            XMLOutputter fmt=new XMLOutputter();
            fmt.output(doc,xmlwriter);
            fmt.output(doc,outstream);
 
 
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
}
9.6.使用FreeMarker/Jsp(WebWork2)生成靜態/動態RSS文件(RSS2.0)
在計劃生成RSS文件的時候,順便搜索了一下JIRA和Confluence的程序,發現它們分別是用模板方式和JSP動態頁面來展示的.於是我也想到兩種方式:
1.用FreeMarker生成靜態文件,適用於更新不是很頻繁的內容.
2.用JSP動態展示,適合更新頻率高,種類繁多的內容.
使用rsslibj庫!
還是以本站的新聞舉例,其中的新聞信息類參考 http://www.jscud.com/srun/news/viewhtml/3_2005_8/76.htm此處不在列出. ,
9.6.1.    先說FreeMarker方式
根據RSS的規範,得到模板如下:
<?xml version="1.0" encoding="UTF-8" ?>
 <rss version="2.0">
 <channel>
  <title>JScud Develop</title>
 <link>http://www.jscud.com/</link>
 <language>zh-cn</language>
 <description >JScud Develop By Scud</description>
 <webMaster>[email protected](scud)</webMaster>
 <lastBuildDate>${rssutil.formatRssDate(now)}</lastBuildDate>
  
   <#list newslist as onenews>
 <item>
   <title>${onenews.title?xml}</title>
   <link>http://www.jscud.com/srun/news/viewhtml/${onenews.htmlFilePath}/${onenews.nid}.htm</link>
   <pubDate>${rssutil.formatRssDate(onenews.addtime)}</pubDate>
   <description><![CDATA[
 ${rssutil.formatRssCData(onenews.showContent)}
   ]]>
   </description>
   </item>
 </#list>
 </channel>
 </rss>
其中的網址和網站名稱可以根據自己的實際情況修改.
我每次取出最新的20條文章來生成RSS,不過內容比較多,生成的RSS文件比較大,看到有的網站的description只是放了文章摘要的內容,這樣文件就小多了.總之是根據自己的需求設計吧.
其中用到的RssUtil函數庫的函數如下(日期的函數參考上一篇文章):
    /**
     * 把]]>替換爲]]&gt;
     * @param content 內容
     * @return 格式化後的內容
     */
    public static String formatRssCData(String content)
    {
        String result = StringFunc.replace(content,"//]//]>","]]&gt;");
       
        return result;
    }
   
    /**
     * 格式化爲xml需要的字符串
     * @param field 內容
     * @return 格式化後的串
     */
    public static String formatString2XML(String field)
    {
        return StringFunc.str2TextXML(field);
    }
   
    public static String getNowDateTime()
    {
        return formatRssDate(DateTime.getNowTimestamp());
    }
 
利用FreeMarker生成靜態文件的代碼如下:
 private Configuration freemarker_cfg = null;
 
    protected Configuration getFreeMarkerCFG()
    {
        if (null == freemarker_cfg)
        {
            // Initialize the FreeMarker configuration;
            // - Create a configuration instance
            freemarker_cfg = new Configuration();
 
            freemarker_cfg.setClassForTemplateLoading(this.getClass(), "/htmlskin");
 
            freemarker_cfg.setDefaultEncoding("GBK");
        }
 
        return freemarker_cfg;
    }
 
    public boolean geneFileByFreeMarker(String templateFileName, Map propMap, String filePath,
                    String fileName, String encode)
    {
        try
        {
            Template t = getFreeMarkerCFG().getTemplate(templateFileName);
 
            File afile = new File(filePath + "/" + fileName);
 
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(afile),
                            encode));
 
            propMap.put("baseurl", PropSet.getStringProp("url.root"));
 
            t.process(propMap, out);
        }
        catch (TemplateException e)
        {
            LogMan.error("Error while processing FreeMarker template " + templateFileName, e);
            return false;
        }
        catch (IOException e)
        {
            LogMan.error("Error while generate File " + fileName, e);
            return false;
        }
 
        return true;
    }
 
新聞系統中調用重新生成RSS文件的代碼如下:
 
    /**
     * 重新生成RSS文件.
     *
     * @param nid 更新的新聞的id,如果不包含在最新的新聞裏,則不更新RSS.nid <1則更新
     *
     * @return 是否成功
     */
    private boolean renewRSS(int nid)
    {
        List newsList = 裝載新聞的代碼
 
        boolean shouldUpdate = false;
        if (nid > 0)
        {
            for (int i = 0; i < newsList.size(); i++)
            {
                NewsItem aNews = (NewsItem) newsList.get(i);
                if (aNews.getNid() == nid)
                {
                    shouldUpdate = true;
                    break;
                }
            }
        }
        else
        {
            shouldUpdate = true;
        }
 
        //不更新,則返回
        if (!shouldUpdate)
        {
            return true;
        }
 
        Map root = new HashMap();
       
        root.put("rssutil",new RSSUtil());
 
        root.put("newslist", newsList);
       
        root.put("now",DateTime.getNowTimestamp());
 
        geneFileByFreeMarker("/news/rss.ftl", root, PropSet.getStringProp("rss.rssdir"), PropSet
                        .getStringProp("rss.rssfile"), "UTF-8");
 
        return true;
    }
在增加或者更新/刪除新聞的地方需要調用這個renewRSS函數.
 
9.6.2.    動態方式JSP
相對靜態方式而言,簡單的多,不過效率上可能就不太好了.
webwork2的Action代碼如下:
        newsList = 裝載新聞代碼
        return SUCCESS;
視圖Jsp如下:
<%@ page contentType="text/xml; charset=UTF-8"%>
<%@ taglib uri="jscud" prefix="jscud" %>
<%@ taglib uri="webwork" prefix="ww" %>
<ww:bean name="’com.jscud.www.util.RSSUtil’" id="rssUtil" />
<?xml version="1.0" encoding="UTF-8" ?>
 <rss version="2.0">
 <channel>
 <title>JScud Develop</title>
 <link>http://www.jscud.com/</link>
 <language>zh-cn</language>
 <description >JScud Develop By Scud</description>
 <webMaster>[email protected](scud)</webMaster>
 <lastBuildDate><ww:property value="#rssUtil.nowDateTime" /></lastBuildDate>
  
   <ww:iterator value="newsList">
 <item>
   <title><ww:property value="#rssUtil.formatString2XML(title)"/></title>
   <link>http://www.jscud.com/srun/news/viewhtml/<ww:property value="htmlFilePath" />/<ww:property value="nid" />.htm</link>
   <pubDate><ww:property value="#rssUtil.formatRssDate(addtime)" /></pubDate>
   <description><![CDATA[
 <ww:property value="#rssUtil.formatRssCData(showContent)"/>
   ]]>
   </description>
   </item>
 </ww:iterator>
 </channel>
 </rss>
jsp的方式簡單多了,上面的jsp裏面還演示了ww:bean的使用 :)
附錄
附錄1:語言編碼
Afrikaans: af
Albanian: sq
Basque: eu
Belarusian: be
Bulgarian: bg
Catalan: ca
Chinese (Simplified): zh-cn
Chinese (Traditional): zh-tw
Croatian: hr
Czech: cs
Danish: da
Dutch: nl
Dutch (Belgium): nl-be
Dutch (Netherlands): nl-nl
English: en
English (Australia): en-au
English (Belize): en-bz
English (Canada): en-ca
English (Ireland): en-ie
English (Jamaica): en-jm
English (New Zealand): en-nz
English (Phillipines): en-ph
English (South Africa): en-za
English (Trinidad): en-tt
English (United Kingdom): en-gb
English (United States): en-us
English (Zimbabwe): en-zw
Estonian: et
Faeroese: fo
Finnish: fi
French: fr
French (Belgium): fr-be
French (Canada): fr-ca
French (France): fr-fr
French (Luxembourg): fr-lu
French (Monaco): fr-mc
French (Switzerland): fr-ch
Galician: gl
Gaelic: gd
German: de
German (Austria): de-at
German (Germany): de-de
German (Liechtenstein): de-li
German (Luxembourg): de-lu
German (Switzerland): de-ch
Greek: el
Hawaiian: haw
Hungarian: hu
Icelandic: is
Indonesian: in
Irish: ga
Italian: it
Italian (Italy): it-it
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章