Подписка

Проекты

Сборник идей для разработок в Delphi и использования их в Интернет. Участвуй в работе коллективного разума!

Google API в Delphi - проект с открытым исходным кодом.


А тут я коплю на лицензию Delphi 2011. Сумма пожертвования не фиксирована.

Друзья блога

Блоги и сообщества

DelphiFeeds.ru - Все Delphi-блоги Рунета О раскрутке блога по программированию Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Статьи по Delphi

Счётчики


Анализ веб сайтов

Рейтинг блогов




Система Orphus

  • 18Feb

    В прошлый раз была разминка. Прочитали несколько узлов – запомнили и успокоились. Сегодня задачка будет по-сложнее – разбор элементов Entry в Google Data Feed. В начале небольшой экскурс в мануалы по Google Data Protocol v.2.0 в часть, касающуюся проблемной области.

    Итак, элементы Entry – это по сути хранилище всевозможных данных для работы со всеми известными API, использующими в своей работе Google Data Protocol. В этих элементах может содержаться всё, что угодно – от контактной информации до наборов данных Google Analytics, FeedBurner и пр.  Однако есть четыре предопределенных структуры для entry (определяются как kinds) – это:

    1. Contact kind – набор данных контакта
    2. Profile Kind – набор данных по профилю пользователя
    3. Event kind – набор данных для события
    4. Message kind – набор данных для сообщения

    ' '
    В каждой из этих структур выделены элементы: обязательные, необязательные и дополнительные.

    Причём обязательных элементов намного меньше, чем всех других. Все элементы, непосредственно относящиеся к GData (“родные” для протокола) определяются как:

    gd:ххх

    где ххх название элемента. В этуже схему включаются перечислители, т.е. те узлы XML, которые содержат только чётко определенные строковые аттрибуты, например элемент gd:eventStatus может содержать в атибуте Value следующие значения:

    http://schemas.google.com/g/2005#event.canceled
    http://schemas.google.com/g/2005#event.confirmed
    http://schemas.google.com/g/2005#event.tentative

    Короче, немного поковырявшись в “родных” элементах протокола можно составить список из 49 различных gd-элементов. Каждый компонент при этом может содержать как текстовую информацию, так и набор аттрибутов в т.ч. перечисляемого типа, integer, boolean и т.д. “Гадость” заключается в том, что отдельные элементы, например gd:feedLink может содержать в себе точно такой же Feedб кокой разбирается в текущий момент, а этот фид опять же может пестрить элементами entry и т.д. и т.п. Короче сходу так просто и не въедешь в тему откуда ноги произрастают у данных. Собственно, отчасти поэтому, отчасти по другой причине и начал разбирать XML в TreeView.
    Помимо всего прочего протокол не запрещает размещать внутри Entry и другие элементы API, например элементы gCal:xxx – определяющие данные для Календаря Google и т.д. Как вариант, можно было бы оставить все как есть, т.е. “выдирать” из фида необходимую информацию, работать с ней и на этом успокоится. Но, мы не будем полагаться на случай (с). Итак, что “умеет” на текущий момент модуль для работы с GData.
    Первое: разбирает Feed и выделяет основные элементы фида, отдельно сохраняя все элементы Entry. При этом можно провести обратную процедуру – передать набор элементов в класс и собрать XML-документ для отправки на сервер.
    Второе: в части работы с Entry. Работа ведется следующим образом:

    1. В каждом элементе Entry определяются как и в Feed корневые элементы, относящиеся непосредственно к узлу, например автор записи, даты публикации и обновления и т.д.

    2. Все оставшиеся элементы фильтруются и выводится список элементов gd-элементов, имеющий следующий вид:

    type
    TGDElement = record
      ElementType : TgdEnum;
      XMLNode: IXMLNode;
    end;
     
    type
      PGDElement = ^TGDElement;
     
    type
    TGDElemntList = class(TList)
    private
      procedure SetRecord(index: Integer; Ptr: PGDElement);
      function GetRecord(index: Integer): PGDElement;
    public
      constructor Create;
      procedure Clear;
      destructor Destroy; override;
      property GDElement[i: Integer]: PGDElement read GetRecord write SetRecord;
    ...
    end;

    3. Оставшиеся элементы пока в расчёт не беруться, т.к. у них опять же будут свои структуры, атрибуты и т.д.

    4. Любой элемент из списка TGDElemntList можно обработать соответсвующие функцией и уже из IXMLNode получить структуру Delphi (record, class), с которой можно делать всё, что угодно: править, дополнять и т.д. Если не нужна структура – не проблема – можно работать непосредственно с узлом IXMLNode.

    Например, так происходит обработка одного из узлов в entry:

    function gdAdditionalName(aXMLNode: IXMLNode): TgdAdditionalNameStruct;
    begin
      if GetGDNodeType(aXMLNode.NodeName) <> ord(egdAdditionalName) then
        raise Exception.Create(Format(rcErrCompNodes,[cGDTagNames[ord(egdAdditionalName)]]));
    try
      if aXMLNode.Attributes['yomi'] <> null then
      Result.yomi := aXMLNode.Attributes['yomi'];
      Result.Text := aXMLNode.Text;
    except
      raise Exception.Create(Format(rcErrPrepareNode, [aXMLNode.NodeName]));
    end;
    end;

    Здесь мы берем узел gd:AdditionalName и представляем его в виде структуры:

    type
    TgdAdditionalNameStruct = record
      yomi: string; //атрибут узла, означающий псевдоним пользователя
      Text: string; //текстовая часть узла - имя
    end;

    Аналогичным образом идёт обработка и более сложных узлов, например, содержащих внутри себя ещё ряд узлов gd:xxx.

    Для конечного пользователя, которому лень смотреть исходник опять же всё умещается в несколько строк кода. Возвращаясь к примеру выше получение структуры TgdAdditionalNameStruct в вызывающей программе будет может быть таким:

    var Node: IXMLNode;
        Struct: TgdAdditionalNameStruct;
    begin
    ...
      Struct:=gdAdditionalName(Node)
    ...
    end;

    Или используя любой цикл перечислить все узлы списка и перебрать все структуры, но это, думаю будет немного лишним.

    В настоящий момент дописываю работы с gd-элементами в фиде. Слудующий шаг – обратная процедура: по предоставленным данным собрать фид и скинуть на сервер. Ну и, конечноже, более плотная работа с Google Celendar API.

    -------------------------
    Фанатеете от супер-героя Бэтмэна? Не мыслите жизнь без напоминалок об этом герое? Тогда специально для Вас batman картинки на любой вкус. Огромное количество картинок всевозможных форматов.

    А пока Вы рассматриваете картинки с Бэтменом Кактус посмотрит на эту ссылку и напишет обзор моего блога. Критика допустима, но сильно чур ногами не бить :)

    Специально для жителей Рязани представляю рязанский кинотеатр Малина По ссылке найдете обзор кинотеатра, включая фотографии интерьера. Очень напоминает Омскую "Галактику" :)
    -------------------------

    Related posts:

    1. Google Data Protocol. Читаем данные фида (Data API feed).
    2. Выбор элементов в SELECT. Delphi.
    3. Война с гоблинами. Часть 3. Разбор завалов.
    4. Google API. Интерфейс ClientLogin для Delphi.
    5. Google API на Delphi. Вспомогательный модуль.

    Автор Vlad в 4:28 pm

    Метки: , ,

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].