Веб-каналы RSS и Atom

Важные API

Получайте или создавайте наиболее актуальное и популярное веб-содержимое с помощью каналов веб-новостей, созданных в соответствии со стандартами RSS и Atom, используя возможности пространства имен Windows.Web.Syndication.

Note

API-интерфейсы Windows.Web.Syndication и Windows.Web.AtomPub — это интерфейсы среда выполнения Windows (WinRT), которые используются в настольных приложениях WinUI 3 (Windows App SDK), а также в приложениях UWP.

Что такое веб-канал?

Веб-лента — это документ, содержащий любое число отдельных записей, состоящих из текста, ссылок и изображений. Обновления, внесённые в ленту, представляют собой новые записи, используемые для продвижения новейшего контента в Сети. Пользователи контента могут использовать приложение для чтения лент, чтобы собирать и отслеживать ленты от множества отдельных авторов, получая быстрый и удобный доступ к новейшим материалам.

Какие стандарты формата веб-канала поддерживаются?

Windows поддерживает получение веб-каналов для стандартов формата RSS от 0.91 до RSS 2.0 и Atom с 0.3 до 1.0. Классы в пространстве имён Windows.Web.Syndication могут определять каналы и элементы канала, способные представлять как элементы RSS, так и Atom.

Кроме того, форматы Atom 1.0 и RSS 2.0 позволяют документам веб-канала содержать элементы или атрибуты, не определенные в официальных спецификациях. Со временем эти пользовательские элементы и атрибуты стали способом задавать предметно-специфическую информацию, используемую другими форматами данных веб-служб, такими как GData и OData. Для поддержки этой добавленной функции класс SyndicationNode представляет универсальные XML-элементы. Использование SyndicationNode с классами из пространства имен Windows.Data.Xml.Dom позволяет приложениям получать доступ к атрибутам, расширениям и любому содержимому, которые могут в них содержаться.

Обратите внимание, что для публикации синдицированного содержимого реализация Windows протокола публикации Atom (Windows.Web.AtomPub) поддерживает только операции с содержимым веб-канала в соответствии со стандартами Atom и Atom Publishing Protocol.

Использование синдикированного содержимого с сетевой изоляцией

Функция сетевой изоляции в Windows позволяет разработчику контролировать и ограничивать доступ к сети приложением Windows. Не всем приложениям может потребоваться доступ к сети. Однако для таких приложений Windows предоставляет различные уровни доступа к сети, которые можно включить, выбрав соответствующие возможности.

Сетевая изоляция позволяет разработчику определять для каждого приложения область требуемого сетевого доступа. Приложение, для которого не определено соответствующее разрешение, не может получить доступ к указанному типу сети и определённому типу сетевых запросов (либо к исходящим запросам, инициированным клиентом, либо как к входящим незапрошенным запросам, так и к исходящим запросам, инициированным клиентом). Возможность настроить и обеспечить соблюдение сетевой изоляции гарантирует, что, если приложение будет скомпрометировано, оно сможет получить доступ только к тем сетям, к которым ему был явно предоставлен доступ. Это значительно сокращает область влияния на другие приложения и на Windows.

Сетевая изоляция затрагивает любые элементы классов в пространствах имён Windows.Web.Syndication и Windows.Web.AtomPub, которые пытаются получить доступ к сети. Windows активно применяет сетевую изоляцию. Вызов элемента класса в пространстве имен Windows.Web.Syndication или Windows.Web.AtomPub, приводящий к обращению к сети, может завершиться сбоем из-за сетевой изоляции, если не включена соответствующая возможность работы в сети.

Сетевые возможности для приложения настраиваются в манифесте приложения при создании приложения. Сетевые возможности обычно добавляются с помощью Visual Studio при разработке приложения. Сетевые возможности также можно задать вручную в файле манифеста приложения с помощью текстового редактора.

Дополнительные сведения об изоляции сети и сетевых возможностях см. в разделе "Возможности" раздела "Основы сети ".

Как получить доступ к веб-каналу

В этом разделе показано, как получить и отобразить веб-канал с помощью классов в пространстве имён Windows.Web.Syndication в вашем приложении Windows, написанном на C#.

Prerequisites

Чтобы убедиться, что приложение Windows готово к сети, необходимо задать все сетевые возможности, необходимые в файле project Package.appxmanifest. Если приложению необходимо подключиться в качестве клиента к удаленным службам в Интернете, потребуется возможность InternetClient . Дополнительные сведения см. в разделе "Возможности" в разделе "Основы сети ".

Получение синдицированного контента из веб-ленты

Теперь мы рассмотрим пример кода, демонстрирующий, как получить ленту, а затем отобразить каждый отдельный элемент, содержащийся в ней. Прежде чем мы сможем настроить и отправить запрос, мы определим несколько переменных, которые будем использовать в ходе этой операции, и инициализируем экземпляр SyndicationClient, который определяет методы и свойства, которые мы будем использовать для получения и отображения канала.

Конструктор URI создает исключение, если uriString , переданный конструктору, не является допустимым универсальным кодом ресурса (URI). Поэтому мы проверяем uriString с помощью блока try/catch.

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

Note

Примеры JavaScript в этой статье используют WinJS (библиотека Windows для JavaScript), которая является устаревшей платформой для приложений JavaScript UWP. Эти примеры предоставляются только для справки и не рекомендуются для разработки новых приложений.

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 ), учетные данные прокси -сервера (свойство ProxyCredential ) и заголовки HTTP (метод SetRequestHeader ). После настройки основных параметров запроса — корректный объект Uri, созданный из строки URI-адреса веб-канала, предоставленной приложением. Затем объект URI передается функции GetFeedAsync для запроса веб-канала.

Предполагая, что содержимое нужного веб-канала было возвращено, пример кода выполняет итерацию каждого элемента веб-канала, вызывая displayCurrentItem (который мы определяем рядом), чтобы отображать элементы и их содержимое в виде списка через пользовательский интерфейс.

Необходимо написать код для обработки исключений при вызове большинства асинхронных сетевых методов. Обработчик исключений может получить более подробную информацию о причине исключения, чтобы лучше понять ошибку и принять соответствующие решения.

Метод RetrieveFeedAsync создает исключение, если соединение не удалось установить с HTTP-сервером или объектом URI , не указывает на допустимый веб-канал AtomPub или RSS. Пример кода 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 , работающую с каждым элементом, и отображаем ее содержимое с помощью различных именованных элементов пользовательского интерфейса.

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 linkElement = document.getElementById("Link");
    linkElement.innerText = link;
    linkElement.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 — нет. Однако к элементам расширения в элементе веб-канала, которые не поддерживаются ни одним из этих стандартов (например, к элементам расширения Dublin Core), можно получить доступ с помощью свойства SyndicationItem.ElementExtensions, а затем отобразить их, как показано в следующем примере кода.

    //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
    });
}