WordPress. Робота з XML-RPC в Delphi. Коментарі (продовження), Різне, Програмування, статті

Джерело: WebDelphi


Минулого разу я розглядав процедуру отримання коментарів з блогу WordPress з використанням XML-RPC.


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

Як ви пам’ятаєте, будь-яка структура (struct) в XML-RPC має такий зміст:

– <struct>
– <member> назва Значення
</member>

тобто кожен елемент має свою назву і значення. Перше, що спадає на думку в плані інтерпретації цього коду в 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 схвалених.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*