Подписка

Проекты

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

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


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

Друзья блога

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

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

Счётчики


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

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




Система Orphus

  • 28Jan

    В прошлый раз я рассматривал процедуру получения комментариев из блога WordPress с использованием XML-RPC.

    Сегодня продолжим разбираться с вопросами использование структур XML-RPC в Delphi и немного “приукрасим” нашу Delphi-функцию по чтению комментариев.

    Как вы помните, любая структура (struct) в XML-RPC имеет следующее содержание:

    - <struct>
    - <member>
     <name>название</name>
    - <value><int>значение</int></value>
     </member>
    '
    '
    
    

    то есть каждый элемент имеет свое название и значение. Первое, что приходит на ум в плане интерпретации этого кода в Delphi – создать динамический массив записей (record). Например таких:

    type
    TSimpleType = (tsInt, tsI4, tsString, tsDouble, tsDateTime, tsBase64, tsBoolean);
     
    type
    TStructElement = packed record
      Name : string;
      SType: TSimpleType;
      Value: string;
    end;

    Таким образом, мы всегда можем определить какой тип данных содержит член структуры и правильно его записать в XML-документ.

    Пока остановимся на этом варианте. Функция добавления структуры в уже созданный XML-документ может быть такой:

    procedure TBlog.SetStructure(Struct: TStructArray; Document: PXMLDocument);
    var i:integer;
         Root,Member: IXMLNode;
    begin
    if (Length(Struct)=0) or(Document^.IsEmptyDoc) then Exit;
    Root:=Document^.DocumentElement.ChildNodes.FindNode('params').AddChild('param').AddChild('struct');
    for i:= 0 to Length(Struct) - 1 do
      begin
        member:=Root.AddChild('member');
        member.AddChild('name').NodeValue:=Struct[i].Name;
        case Struct[i].SType of
           tsInt,tsI4:member.AddChild('value').AddChild('int').NodeValue:=Struct[i].Value;
         tsString:  member.AddChild('value').AddChild('string').NodeValue:=Struct[i].Value;
         tsDouble:  member.AddChild('value').AddChild('double').NodeValue:=Struct[i].Value;
         tsDateTime:member.AddChild('value').AddChild('dateTime.iso8601').NodeValue:=Struct[i].Value;
         tsBase64:  member.AddChild('value').AddChild('base64').NodeValue:=Struct[i].Value;
          tsBoolean: member.AddChild('value').AddChild('boolean').NodeValue:=Struct[i].Value;
        end;
      end;
    end;

    Признаться, был позыв сделать запись содержащую поле типа Variant и избавиться от TSimpleType, но что-то я засомневался по поводу верной интерпретации полей типа boolean. Не будет ли в случае задание булевой переменной в виде 0-1 программа записывать в документ поле структуры с типом int?

    Чтобы избежать подобных недоразумений пришлось использовать лишнее поле и на основании его записывать данные в XML-документ.

    Теперь вернемся к нашей процедуре чтения комментариев. В прошлый раз мы остановились на том, что использовали в качестве одного из параметров отдельной записи record, описывающей поле filter в запросе. еперь процедуру можно немного видоизменить и включить во входные параметры наш новый тип данных.

    У меня, после недолгих преобразований, получилась следующая процедура для чтения комментариев из блога WordPress:

    function TBlog.GetComments(const CommentStruct: TStructArray): TComments;
    var i,j:integer;
      Doc:  IXMLDocument;
      Values: IDOMNodeList;//все тэги value массива
      Members: IDOMNodeList;//все тэги member элемента value
      List: TStringList;
    begin
      Doc:=GetDocument('wp.getComments');
      SetParam(tsInt,'1',@Doc);
      SetParam(tsString,FUserName,@Doc);
      SetParam(tsString,FPassword,@Doc);
      SetStructure(CommentStruct,@Doc);
      SendQuery(@Doc,FURL);
      Values:=Doc.DOMDocument.getElementsByTagName('data').item[0].childNodes;
      SetLength(Result,Values.length);
    for i:= 0 to Values.length-1 do
      begin
        Members:=Values[i].firstChild.childNodes;//получили все members для 1 value
        for j:=0 to Members.length - 1 do
           begin
             with Result[i]do
               begin
                 case j of
                   0:Result[i].date_created_gmt:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   1:Result[i].user_id:=StrToInt((Members[j].lastChild.firstChild as IDOMNodeEx).text);
                 2:Result[i].comment_id:=StrToInt((Members[j].lastChild.firstChild as IDOMNodeEx).text);
                   3:Result[i].parent:=StrToInt((Members[j].lastChild.firstChild as IDOMNodeEx).text);
                   4:Result[i].status:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   5:Result[i].content:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   6:Result[i].link:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   7:Result[i].post_id:=StrToInt((Members[j].lastChild.firstChild as IDOMNodeEx).text);
                   8:Result[i].post_title:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   9:Result[i].author:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   10:Result[i].author_url:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   11:Result[i].author_email:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
                   12:Result[i].comment_type:=(Members[j].lastChild.firstChild as IDOMNodeEx).text;
             end;
         end;
      end;
    end;
    end;

    Напомню, что тип TComments – это динамический массив записей вида:

    type
    TComment = packed record
      date_created_gmt: string;
      user_id: integer;
      comment_id: integer;
      parent: integer;
      status: string;
      content: string;
      link  :string;
      post_id: integer;
      post_title: string;
      author: string;
      author_url: string;
      author_email: string;
      author_ip : string;
      comment_type : string;
    end;

    Двигаемся дальше. С одной стороны все вроде бы замечательно – создали переменную типа TStructArray, передали в качестве параметр процедуры и получили ответ. Но с другой стороны – что делать если в запросе должна быть структура на 10 полей? 20? Это ж замаешься для каждого поля указывать название, тип, значение. Я решил эту проблему следующим образом (пока черновой вариант). Создаем функцию для создания struct на определенный запрос. В нашем случае это wp.GetComments:

    function TBlog.GetCommentStructure(post_id: integer; status: string; number,
    offset: integer): TStructArray;
    begin
      Result:=nil;
      if post_id&gt;-1 then
        begin
          Setlength(Result,length(Result)+1);
          Result[length(Result)-1].Name:='post_id';
          Result[length(Result)-1].SType:=tsInt;
          Result[length(Result)-1].Value:=IntToStr(post_id);
        end;
    if length(status)&gt;0 then
      begin
        Setlength(Result,length(Result)+1);
        Result[length(Result)-1].Name:='status';
        Result[length(Result)-1].SType:=tsString;
        Result[length(Result)-1].Value:=status;
      end;
    if number&gt;-1 then
      begin
        Setlength(Result,length(Result)+1);
        Result[length(Result)-1].Name:='number';
        Result[length(Result)-1].SType:=tsInt;
        Result[length(Result)-1].Value:=IntToStr(number);
      end;
    if offset&gt;-1 then
      begin
        Setlength(Result,length(Result)+1);
        Result[length(Result)-1].Name:='offset';
        Result[length(Result)-1].SType:=tsInt;
        Result[length(Result)-1].Value:=IntToStr(offset);
      end;
    end;

    и уже результат этой функции используем для получения комментариев:

    function TBlog.LoadComments(const Post_id: integer; Numder, Offset: integer; Status: string): TComments;
    begin
      Result:=GetComments(GetCommentStructure(Post_id,Status,Numder,Offset));
    end;

    При этом, если задать параметрам типа integer значения -1, а в параметре статус передать пустую строку, то функция вернет комментарии из блога по умолчанию, т.е. последние 10 одобренных.

    ----------------------
    Неделька выдалась напряженной...как жаль, что не могу отдохнуть и расслабиться тут - живу не в Москве :(.

    Нужен простой сайт-визитка, но нет денег? Не проблема - сайт визитка бесплатно для Вас и Вашего бизнеса
    ----------------------

    Related posts:

    1. WordPress. Работа с XML-RPC в Delphi. Читаем комментарии.
    2. WordPress. Работа с XML-RPC в Delphi.
    3. XML-RPC. Как получить URL’ы постов блога?
    4. XML-RPC в Delphi. Первое знакомство с WordPress изнутри.
    5. API Яндекс.Спеллера в Delphi.

    Автор Vlad в 10:16 pm

    Метки: , ,

Ваш ответ

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

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