Опубликован: 15.05.2013 | Доступ: свободный | Студентов: 264 / 9 | Длительность: 24:25:00
Специальности: Системный архитектор
Лекция 9:

Синдикация

< Лекция 8 || Лекция 9: 1234 || Лекция 10 >
Аннотация: Работа с синдицированными веб-каналами полностью поддерживается приложениями для Магазина Windows. WinRT предлагает дополнительные API для работы с синдицированным содержимым.

Когда мы впервые столкнулись с выполнением запросов XmlHttpRequests с помощью WinJS.XHR в Главе 3 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", мы запрашивали RSS-ленту из Блога для разработчиков приложений для Windows 8, пользуясь URI http://blogs.msdn.com/b/windowsappdev/rss.aspx . Затем мы узнали, что WinJS.xhr возвращает promise-объект, результат которого содержит свойство responseXML , которое имеет тип DomParser, с его помощью можно обойти структуру DOM и так далее.

Работа с синдицированными веб-каналами, наподобие вышеупомянутой, полностью поддерживается приложениями для Магазина Windows. На самом деле, материал "Доступ к сводному содержимому и управление им" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh452973.aspx) описывает именно этот процесс, компоненты которого показаны в примере "Интеграция содержимого и элементов управления веб-сервисов" (http://code.msdn.microsoft.com/windowsapps/Mashup-Sample-10689f5b).

Тем не менее, WinRT предлагает дополнительные API для работы с синдицированным содержимым. Один из них, Windows.Web.Syndication, предлагает более структурированный подход для работы с RSS-каналами. Другой, Windows.Web.AtomPub, предоставляет средства для публикации записей каналов и управления ими. И то и другое предоставлены в WinRT для языков, у которых нет средств для достижения тех же целей, но, как у разработчика, работающего с JavaScript, у вас есть выбор.

Чтение RSS-каналов

Основной класс в Windows.Web.Syndication (http://msdn.microsoft.com/library/windows/apps/br244529.aspx) это SyndicationClient (http://msdn.microsoft.com/library/windows/apps/windows.web.syndication.syndicationclient.aspx). Для работы с любым каналом сначала создают экземпляр этого класса и задают необходимые свойства. Это следующие свойства: serverCredential (типа PasswordCredential), proxyCredential (еще одно свойство типа PasswordCredential), timeout (в миллисекундах, по умолчанию 30000 или 30 секунд), maxResponseBufferSize (средство для защиты от потенциальных серверов злоумышленников), и bypassCacheOnRetrieve (логическое значение, которое указывает на то, всегда ли нужно получать новые данные с сервера ). Так же можно произвести необходимое количество вызовов его метода setRequestHeader (передавая имя и значение) для настройки заголовка XmlHttpRequest.

Последний шаг заключается в вызове метода SyndicationClient.retrieveFeedAsync с URI нужного RSS-канала (типа Windows.Foundation.Uri). Вот код, взятый из примера "Синдикация" (http://code.msdn.microsoft.com/windowsapps/Syndication-sample-07ef6b0d), который получает RSS-канал блога "Создание Windows 8" (http://blogs.msdn.com/b/b8/rss.aspx):

 uri = new Windows.Foundation.Uri("http://blogs.msdn.com/b/b8/rss.aspx");

   var client = new Windows.Web.Syndication.SyndicationClient();
   client.bypassCacheOnRetrieve = true;
   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) {
    // feed это объект SyndicationFeed

Результат выполнения retrieveFeedAsync – это объект Windows.Web.Syndication.SyndicationFeed (http://msdn.microsoft.com/library/windows/apps/windows.web.syndication.syndicationfeed.aspx), то есть, SyndicationClient это то, что вы использовали для взаимодействия с свервисом, и когд вы получаете канал, вы получаете объект, с помощью которого вы можете затем обработать полученные данные. Если вы взглянете на SyndicationFeed , воспользовавшись вышеприведенной ссылкой, вы увидите, что он наполнен свойствами, которые представляют собой все части канала, такие, как authors, categories, items, title, и так далее. Некоторые из них представлены другими классами в Windows.Web.Syndication, или их коллекциями, когда более простых типов недостаточно: SyndicationAttribute, SyndicationCategory, SyndicationContent, SyndicationGenerator, SyndicationItem, SyndicationLink, SyndicationNode, SyndicationPerson, и SyndicationText. Оставляю разъяснение подробностей обо всём этом документации.

Кое-что из этого мы можем увидеть в примере, взятом из обработчика завершения для retrieveFeedAsync. Позвольте мне представить аннотированный вариант этого кода:

client.retrieveFeedAsync(uri).done(function (feed) {
  currentFeed = feed;

  var title = "(no title)";

  // currentFeed.title это объект SyndicationText
  if (currentFeed.title) {
  title = currentFeed.title.text;
  }
  // currentFeed.items это коллекция SyndicationItem (массив)
  currentItemIndex = 0;
  if (currentFeed.items.size>0) {
  displayCurrentItem();
  }
  }

  // ...

  function displayCurrentItem() {
  // Элемент будет иметь тип SyndicationItem

  var item = currentFeed.items[currentItemIndex];

  // Отображение номера элемента.
  document.getElementById("scenario1Index").innerText = (currentItemIndex + 1) + " of "
  + currentFeed.items.size;

  // Отображение заголовка (item.title это еще один SyndicationText).
  var title = "(no title)";
  if (item.title) {
  title = item.title.text;
  }
  document.getElementById("scenario1ItemTitle").innerText = title;

  // Отображение основной ссылки (item.links это коллекция объектов SyndicationLink).
  var link = "";
  if (item.links.size>0) {
  link = item.links[0].uri.absoluteUri;
  }

  var scenario1Link = document.getElementById("scenario1Link");
  scenario1Link.innerText = link;
  scenario1Link.href = link;

  // Отображение тела в виде HTML (item.content это объект SyndicationContent, item.summary это
  // объект SyndicationText object).
  var content = "(no content)";
  if (item.content) {
  content = item.content.text;
  }
  else if (item.summary) {
  content = item.summary.text;
  }
  document.getElementById("scenario1WebView").innerHTML = window.toStaticHTML(content);

  // Отображение расширений элемента. Коллекция elementExtensions содержит дополнительные
  // дочерние элементы в текущем элементе, которые не принадлежат станартам Atom или RSS
  // (например, элементы расширения Dublin Core). Создавая их массив, мы можем создать
  // WinJS.Binding.List, который можно легко вывести в ListView.
  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 });
}

Видимо, это очевидно, что API, лежащие в основе всего этого, скорее всего, просто используют API XmlDocument для получения этих свойств канала. На самом деле его getXmlDocument возвращает этот XmlDocument, если вам понадобится доступ к нему в собственных целях.

Так же вы можете создать объект SyndicationFeed на основе XML для канала, который у вас уже есть. Например, если вы получили содержимое канала с использованием WinJS.xhr, вы можете создать новый объект SyndicationFeed и вызвать его метод load со свойством XHR responseXML. Затем вы можете работать с каналом с помощью иерархии класса. При использовании API Windows.Web.AtomPub для управления каналом, вы так же создаете новый или обновленный элемент SyndicationItem для передачи по каналам связи, устанавливаете его значения посредством других объектов в его иерархии. Скоро мы это увидим.

Еще одно примечание: если retrieveFeedAsync выдает исключение, которое можно получить с помощью обработчика ошибок, который вы предоставили в метод done соответствующего promise-объекта, вы можете преобразовать код ошибки в значение SyndicationErrorStatus. Вот, как это используется в обработчике ошибок примера:

       
function onError(err) {
// Сранивает номер ошибки со значением SyndicationErrorStatus. Используйте
// Windows.Web.WebErrorStatus.getStatus() для получения кодов статусов HTTP - ошибок.
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.");
}
}
< Лекция 8 || Лекция 9: 1234 || Лекция 10 >