Календарь на Май 2024 года: calendar2008.ru/2024/may/
Навигация
Главная »  Delphi 

WordPress. Работа с XML-RPC в Delphi. Комментарии (продолжение)


Источник: webdelphi
Источник: WebDelphi

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

Сегодня продолжим разбираться с вопросами использование структур XML-RPC в Delphi и немного "приукрасим" нашу Delphi-функцию по чтению комментариев. Как вы помните, любая структура (struct) в XML-RPC имеет следующее содержание:

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

1 2 3 4 5 6 7 8 9 
type TSimpleType = (tsInt, tsI4, tsString, tsDouble, tsDateTime, tsBase64, tsBoolean);   type TStructElement = packed record Name : string; SType: TSimpleType; Value: string; end;
Таким образом, мы всегда можем определить какой тип данных содержит член структуры и правильно его записать в XML-документ.

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 
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 - это динамический массив записей вида:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 
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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 
function TBlog.GetCommentStructure(post_id: integer; status: string; number, offset: integer): TStructArray; begin Result:=nil; if post_id>-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)>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>-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>-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;
и уже результат этой функции используем для получения комментариев:

1 2 3 4 
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 одобренных.



 

 Как научить программу общаться.
 Аналитика: Рынок средств разработки в 2006 году.
 KOL - кодоэкономичная объектная библиотека для Delphi.
 Шифрование в Delphi (исходники).
 Embarcadero объявляет о выходе FireDAC.


Главная »  Delphi 

© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено.