RSS/Atom 摘要
重要 API
使用 Windows.Web.Syndication 命名空間中的功能,根據 RSS 和 Atom 標準產生的同步發行摘要,擷取或建立最新的熱門 Web 內容。
什麼是摘要?
Web 摘要是一個文件,其中包含由文字、連結和影像組成的任意數目個別項目。 對摘要所做的更新會以新項目的形式,用來在網路上推廣最新的內容。 內容取用者可以使用摘要讀取器應用程式來彙總和監視任意數目個別內容作者的摘要,並快速且方便地存取最新內容。
支援哪些摘要格式標準?
通用 Windows 平台 (UWP) 支援從 0.91 到 RSS 2.0 的 RSS 格式標準,以及從 0.3 到 1.0 的 Atom 標準的摘要擷取。 Windows.Web.Syndication 命名空間中的類別可以定義能夠代表 RSS 和 Atom 元素的摘要和摘要項目。
此外,Atom 1.0 和 RSS 2.0 格式都允許其摘要文件包含官方規格中未定義的元素或屬性。 隨時間發展,這些自訂元素和屬性已成為定義 GData 和 OData 等其他 Web 服務資料格式所取用網域特定資訊的方式。 為了支援這項新增的功能,SyndicationNode 類別代表泛型 XML 元素。 在 Windows.Data.Xml.Dom 命名空間中使用 SyndicationNode,可讓應用程式存取其可能包含的屬性、延伸模組和任何內容。
請注意,對於同步發行內容的發佈,Atom 發佈協議 (Windows.Web.AtomPub) 的 UWP 實作僅支援根據 Atom 和 Atom 發佈標準的摘要內容作業。
使用同步發行內容搭配網路隔離
UWP 中的網路隔離功能可讓開發人員控制及限制 UWP 應用程式的網路存取。 並非所有應用程式都需要存取網路。 不過,針對那些執行的應用程式,UWP 會提供不同層級的網路存取權,可藉由選取適當的功能來啟用。
網路隔離可讓開發人員為每個應用程式定義必要的網路存取範圍。 未定義適當範圍的應用程式無法存取指定的網路類型,以及特定類型的網路要求 (輸出用戶端起始的要求或輸入未經請求的要求和輸出用戶端起始的要求)。 設定與強制執行網路隔離可以確保受到危害的應用程式僅能存取已經明確授與應用程式存取權的網路。 這會大幅減少了對其他應用程式和 Windows 的影響範圍。
網路隔離會影響 Windows.Web.Syndicate 和 Windows.Web.AtomPub 命名空間中嘗試存取網路的任何類別元素。 Windows 會主動強制執行網路隔離。 如果沒有啟用適當的網路功能,則對 Windows.Web.Synmination 或 Windows.Web.AtomPub 命名空間中的類別元素呼叫可能會因網路隔離而導致網路存取失敗。
建置應用程式時,應用程式的網路功能會在應用程式資訊清單中設定。 開發應用程式時,通常會使用 Microsoft Visual Studio 2015 來新增網路功能。 您也可以使用文字編輯器,在應用程式資訊清單檔案中手動設定網路功能。
如需網路隔離和網路功能的詳細資訊,請參閱網路基本概念主題中的「功能」一節。
如何存取 Web 摘要
本節說明如何在以 C# 或 JavaScript 撰寫的 UWP 應用程式中,使用 Windows.Web.Syndication 命名空間中的類別來擷取和顯示 Web 摘要。
先決條件
若要確保您的 UWP 應用程式已準備好網路,您必須設定專案 Package.appxmanifest 檔案中所需的任何網路功能。 如果您的應用程式需要以用戶端身分連線到網際網路上的遠端服務,則需要 internetClient 功能。 如需詳細資訊,請參閱網路基本概念主題中的「功能」一節。
從網頁摘要抓取同步發佈內容
現在,我們將檢閱一些示範如何擷取摘要的程式碼,然後顯示摘要所包含的每個個別項目。 在設定和傳送要求之前,我們會定義一些將在作業期間使用的變數,並初始化 SyndicationClient 的執行個體,其會定義我們將用來擷取和顯示摘要的方法和屬性。
如果傳遞至建構函式的 uriString 不是有效的 URI,Uri 建構函式會擲回例外狀況。 因此,我們會使用 try/catch 區塊來驗證 uriString。
Windows.Web.Syndication.SyndicationClient client = new Windows.Web.Syndication.SyndicationClient();
Windows.Web.Syndication.SyndicationFeed feed;
// The URI is validated by catching exceptions thrown by the Uri constructor.
Uri uri = null;
// Use your own uriString for the feed you are connecting to.
string uriString = "";
try
{
uri = new Uri(uriString);
}
catch (Exception ex)
{
// Handle the invalid URI here.
}
var currentFeed = null;
var currentItemIndex = 0;
var client = new Windows.Web.Syndication.SyndicationClient();
// The URI is validated by catching exceptions thrown by the Uri constructor.
var uri = null;
try {
uri = new Windows.Foundation.Uri(uriString);
} catch (error) {
WinJS.log && WinJS.log("Error: Invalid URI");
return;
}
接下來,我們會設定任何伺服器認證來設定要求 (ServerCredential 屬性)、Proxy 認證 (ProxyCredential 屬性) 以及 HTTP 標頭 (SetRequestHeader 方法)。 設定基本要求參數後,會使用應用程式提供的摘要 URI 字串建立有效的 Uri 物件。 然後,Uri 物件會傳遞至 RetrieveFeedAsync 函式,以要求摘要。
假設傳回所需的摘要內容,範例程式碼會逐一查看每個摘要項目,呼叫 displayCurrentItem (我們之後會定義),以透過 UI 將項目及其內容顯示為清單。
呼叫大部分非同步網路方法時,您必須撰寫程式碼來處理例外狀況。 您的例外狀況處理常式可擷取例外狀況發生原因的詳細資訊,以進一步了解失敗並做出適當決策。
如果無法與 HTTP 伺服器建立連線,或 Uri 物件未指向有效的 AtomPub 或 RSS 摘要,RetrieveFeedAsync 方法會擲回例外狀況。 JavaScript 範例程式碼會使用 onError 函式來攔截任何例外狀況,並在發生錯誤時列印出例外狀況的詳細資訊。
try
{
// Although most HTTP servers do not require User-Agent header,
// others will reject the request or return a different response if this header is missing.
// Use the setRequestHeader() method to add custom headers.
client.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
feed = await client.RetrieveFeedAsync(uri);
// Retrieve the title of the feed and store it in a string.
string title = feed.Title.Text;
// Iterate through each feed item.
foreach (Windows.Web.Syndication.SyndicationItem item in feed.Items)
{
displayCurrentItem(item);
}
}
catch (Exception ex)
{
// Handle the exception here.
}
function onError(err) {
WinJS.log && WinJS.log(err, "sample", "error");
// Match error number with an ErrorStatus value.
// Use Windows.Web.WebErrorStatus.getStatus() to retrieve HTTP error status codes.
var errorStatus = Windows.Web.Syndication.SyndicationError.getStatus(err.number);
if (errorStatus === Windows.Web.Syndication.SyndicationErrorStatus.invalidXml) {
displayLog("An invalid XML exception was thrown. Please make sure to use a URI that points to a RSS or Atom feed.");
}
}
// Retrieve and display feed at given feed address.
function retreiveFeed(uri) {
// Although most HTTP servers do not require User-Agent header,
// others will reject the request or return a different response if this header is missing.
// Use the setRequestHeader() method to add custom headers.
client.setRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
client.retrieveFeedAsync(uri).done(function (feed) {
currentFeed = feed;
WinJS.log && WinJS.log("Feed download complete.", "sample", "status");
var title = "(no title)";
if (currentFeed.title) {
title = currentFeed.title.text;
}
document.getElementById("CurrentFeedTitle").innerText = title;
currentItemIndex = 0;
if (currentFeed.items.size > 0) {
displayCurrentItem();
}
// List the items.
displayLog("Items: " + currentFeed.items.size);
}, onError);
}
在上一個步驟中,RetrieveFeedAsync 已傳回要求的摘要內容,而範例程式碼也逐一查看可用的摘要項目。 會使用 SyndicationItem 物件來表示每個項目,其中包含相關發佈內容標準 (RSS 或 Atom) 提供的所有項目屬性和內容。 在下列範例中,我們觀察 displayCurrentItem 函式會透過每個項目運作,並透過各種具名 UI 元素顯示其內容。
private void displayCurrentItem(Windows.Web.Syndication.SyndicationItem item)
{
string itemTitle = item.Title == null ? "No title" : item.Title.Text;
string itemLink = item.Links == null ? "No link" : item.Links.FirstOrDefault().ToString();
string itemContent = item.Content == null ? "No content" : item.Content.Text;
//displayCurrentItem is continued below.
function displayCurrentItem() {
var item = currentFeed.items[currentItemIndex];
// Display item number.
document.getElementById("Index").innerText = (currentItemIndex + 1) + " of " + currentFeed.items.size;
// Display title.
var title = "(no title)";
if (item.title) {
title = item.title.text;
}
document.getElementById("ItemTitle").innerText = title;
// Display the main link.
var link = "";
if (item.links.size > 0) {
link = item.links[0].uri.absoluteUri;
}
var link = document.getElementById("Link");
link.innerText = link;
link.href = link;
// Display the body as HTML.
var content = "(no content)";
if (item.content) {
content = item.content.text;
}
else if (item.summary) {
content = item.summary.text;
}
document.getElementById("WebView").innerHTML = window.toStaticHTML(content);
//displayCurrentItem is continued below.
如先前所建議,SyndicationItem 物件所代表的內容類型會根據用於發佈摘要的摘要標準 (RSS 或 Atom) 而有所不同。 例如,Atom 摘要能夠提供參與者清單,但 RSS 摘要則無法提供。 不過,您可以使用 SyndicationItem.ElementExtensions 屬性,存取和顯示兩個標準都不支援的摘要項目所包含的延伸元素 (例如,Dublin Core 延伸元素),如下列範例程式碼所示範。
//displayCurrentItem continued.
string extensions = "";
foreach (Windows.Web.Syndication.SyndicationNode node in item.ElementExtensions)
{
string nodeName = node.NodeName;
string nodeNamespace = node.NodeNamespace;
string nodeValue = node.NodeValue;
extensions += nodeName + "\n" + nodeNamespace + "\n" + nodeValue + "\n";
}
this.listView.Items.Add(itemTitle + "\n" + itemLink + "\n" + itemContent + "\n" + extensions);
}
// displayCurrentItem function continued.
var bindableNodes = [];
for (var i = 0; i < item.elementExtensions.size; i++) {
var bindableNode = {
nodeName: item.elementExtensions[i].nodeName,
nodeNamespace: item.elementExtensions[i].nodeNamespace,
nodeValue: item.elementExtensions[i].nodeValue,
};
bindableNodes.push(bindableNode);
}
var dataList = new WinJS.Binding.List(bindableNodes);
var listView = document.getElementById("extensionsListView").winControl;
WinJS.UI.setOptions(listView, {
itemDataSource: dataList.dataSource
});
}