Поиск по блогу

четверг, 18 декабря 2008 г.

RSS в виде дерева (TTreeView в Delphi)

Приятно, когда есть обратная связь с блога. Когда уточняют что-либо или задают вопросы. Поэтому в продолжение к статье об отображении XML в виде дерева напишу еще эту — об отображении RSS в TreeView.

Про структуру RSS я уже писала. Задача сводится к малому: пройтись по всем записям, разобрать их элементы и представить в виде дерева "Адрес RSS — Записи".

Для достижения своих целей будем оперировать данными типов IXMLNode и IXMLNodeList.

nd : IXMLNode;
firstTier : IXMLNodeList;


DocumentElement — возвращает корневой объект документа.
childNodes — возвращает список прямых потомков вершины. Далее с дочерними узлами можно работать просто как с элементами списка. Например, узнать имя узла, можно будет firstTier[i].NodeName.

Итак, исследуем код RSS-фида, который генерируется feedburner-ом. Видим, что самый простой способ получить все записи, — это из списка узлов первого уровня выбрать узлы с именем entry, а потом каждый из этих узлов обработать (выделить нужные нам дочерние узлы content, published (дата публикации) и link (у узла link нам понадобится значение атрибута href)).


XMLDocument1.FileName := 'MyRSSFeed.xml';
XMLDocument1.Active := true;

nd := XMLDocument1.DocumentElement;

TreeView1.Items.AddChild(nil,edtRSSURL.Text);
firstTier := nd.childNodes;
for i := 0 to firstTier.Count-1 do
begin
if firstTier[i].NodeName = 'entry' then
begin
nd := firstTier[i];
ProcessItem();
end;
end;


Что касается обработки записей. Все просто со значениями узлов с именами content и published, так как такие узлы встречаются один раз. А вот узлов с именем link встречается несколько.

<link rel="replies" type="application/atom xml" href="http://mama-karlo.blogspot.com/feeds/6599339245902184370/comments/default" title="..." />
<link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=29395559131211965&amp;postID=6599339245902184370" title="..." />
<link rel="edit" type="application/atom xml" href="http://www.blogger.com/feeds/29395559131211965/posts/default/6599339245902184370?v=2" />
<link rel="self" type="application/atom xml" href="http://www.blogger.com/feeds/29395559131211965/posts/default/6599339245902184370?v=2" />
<link rel="alternate" type="text/html" href="http://mama-karlo.blogspot.com/2008/12/blog-post_16.html" title="..." />


Нам нужно выбрать только тот узел, у которого значение атрибута rel равно alternate. В итоге получаем код:

type
PRSSFeedData = ^TRSSFeedData;
TRSSFeedData = record
URL : string;
Description : string;
Date : string;
end;

procedure ProcessItem();
var
rssFeedData : PRSSFeedData;
tn : TTreeNode;
title : string;
j : integer;
begin
New(rssFeedData);

title := nd.ChildNodes.FindNode('title').Text;

with nd.ChildNodes do
begin
rssFeedData.Description := FindNode('content').Text;
rssFeedData.Date := FindNode('published').Text;
end;

for j := 0 to nd.ChildNodes.Count-1 do
if (nd.ChildNodes[j].NodeName = 'link') and (nd.ChildNodes[j].GetAttribute('rel') = 'alternate') then
begin
rssFeedData.URL := nd.ChildNodes[j].GetAttribute('href');
break;
end;

tn := TreeView1.Items.AddChild(TreeView1.Items.GetFirstNode, title);
tn.Data := rssFeedData;
end;


Вот небольшое приложение, на примере которого можно поразбираться, как все работает.
RSS-feed in TreeView, Delphi

Исходники можно скачать здесь.

P.S. Спасибо благодарным читателям, которые шлют на пиво! %D

Статьи схожей тематики:



2 комментария:

  1. Не универсальным дерево получилось-то...оказывается фидбёрнер фидбернеру рознь. Сейчас смотрю XML-схему для feed2 от Гугля - там получается, что узел с описанием статьи находится на уровень ниже, чем в этом примере узел entry. Получается, что теперь так с ходу к нужному узлу и не попасть? Только перебирать все узлы в поисках нужного, а потом с ним работать?

    ОтветитьУдалить
  2. Привет! Да, код не универсальный, об универсальности я и не говорила. Я просто привела пример конкретно для фида, генерируемого фидбернером. Некоторые сайты генерируют фиды по-своему. Фидбернер их более-менее приводил к одному виду. С переносом фида на гугль - надо брать фид и изучать. К сожалению, мне сейчас этим заняться некогда, но я уверена, что данные там систематизированы не хуже ;)

    ОтветитьУдалить

Комментарии модерируются, вопросы не по теме удаляются, троллинг тоже.

К сожалению, у меня нет столько свободного времени, чтобы отвечать на все частные вопросы, так что, может, свой вопрос лучше задать на каком-нибудь форуме?

Поделиться