Нужно было освоить формат JSON. Конкретнее - его распарсивание. После некоторых поисков была найдена нужная библиотека и примеры.
"system":{version:"1.0"},
"chains":[1,2],
"devices":[
{"id":1,"type":"07"}
]
}
Из них три класса: TJSONData , TJSONParser и TJSONObject.
TJSONObject - это тот объект который подходит для хранения и манипулирования JSON структурой. Хранить буду в нем.
{"test":{
"system":{version:"1.0"},
"chains":[1,2],
"devices":[
{"id":1,"type":"07"}
]
}}
Это обстоятельство не очень понравилось. Написал небольшой класс с методом загрузки структуры из строки один в один.
unit json;
interface
uses
SysUtils, fpjson,jsonparser;
type
TJSON = class(TJSONObject)
public
function ifExistKey(aKey: string): Boolean;
function Parse(aString: string): Boolean;
end;
implementation
function TJSON.ifExistKey(aKey: string): Boolean;
begin
result:=(Find(aKey)<>nil);
end;
function TJSON.Parse(aString: string): Boolean;
var
D : TJSONData;
P : TJSONParser;
i:Integer;
begin
result:=false;
P:=TJSONParser.Create(aString);
D:=P.Parse;
Clear;
try
for i:=0 to D.Count-1 do begin
Add(TJSONObject(D).Names[i],TJSONObject(D).Items[i]);
end;
except
FreeAndNil(P);
exit;
end;
FreeAndNil(P);
result:=true;
end;
end.
метод Parse(s:String) возвращает false в случае ошибки
метод ifExistKey(key:String) проверяет есть ли узел с указанным ключом на главном уровне.
Использую примерно так:
var
JS:TJSON;
fd:THandle;
filename:string;
Buffer:String;
begin
filename:=IncludeTrailingBackslash(ExtractFileDir(ParamStrUTF8(0)))+'test.json';
fd:=FileOpenUTF8(filename, fmOpenRead);
SetLength(Buffer,FileSize(filename));
FileRead(fd,Buffer[1],Length(Buffer));
FileClose(fd);
JS:=TJSON.Create;
JS.Parse(Buffer);
ShowMessage(JS.FormatJSON); // чтобы посмотреть что там у нас
end;
Краткое описание класса TJSONObject.
FormatJSON:String // выводит в строку всю структуру JSON
Find(Const AName : String) : TJSONData; // находит указанный узел по имени ключа
Get(Const AName : String) ???? // возвращает данные по ключу. функций много, по количеству возвращаемых типов. Смотрите справку.
Clear; // очистка
Add // опять же много функций, для каждого типа своя.
Delete(ключ или индекс) // удаляет узел
свойство Names[Index : Integer] // узнать название узла
свойство Items[Index: Integer]: TJSONData // получить данные узла
свойство Elements[AName: string] : TJSONData // получить данные узла по имени ключа
свойство Objects[AName : String] : TJSONObject // получить данные узла по имени ключа в виде объекта TJSONObject
Ну и конечно же функция Count - количество узлов на главном уровне.
JSON читаю из файла в строку (это для тестирования, потом он будет изначально в строке) и передаю в функцию.
{"system":{version:"1.0"},
"chains":[1,2],
"devices":[
{"id":1,"type":"07"}
]
}
Распарсенный JSON мне нужно хранить в переменной и периодически обращаться к нему для получения данных.
Для работы мне понадобилось два модуля : fpjson, jsonparser.Из них три класса: TJSONData , TJSONParser и TJSONObject.
TJSONObject - это тот объект который подходит для хранения и манипулирования JSON структурой. Хранить буду в нем.
TJSONParser - парсит строку и выдает результат в виде объекта TJSONData. TJSONData - довольно бестолковый класс, у него мало методов для работы со структурой. Когда пытался добавить данные в TJSONObject выяснилось что они добавляются только как дочерние объекты, то есть например на ключ test:
{"test":{
"system":{version:"1.0"},
"chains":[1,2],
"devices":[
{"id":1,"type":"07"}
]
}}
Это обстоятельство не очень понравилось. Написал небольшой класс с методом загрузки структуры из строки один в один.
unit json;
interface
uses
SysUtils, fpjson,jsonparser;
type
TJSON = class(TJSONObject)
public
function ifExistKey(aKey: string): Boolean;
function Parse(aString: string): Boolean;
end;
implementation
function TJSON.ifExistKey(aKey: string): Boolean;
begin
result:=(Find(aKey)<>nil);
end;
function TJSON.Parse(aString: string): Boolean;
var
D : TJSONData;
P : TJSONParser;
i:Integer;
begin
result:=false;
P:=TJSONParser.Create(aString);
D:=P.Parse;
Clear;
try
for i:=0 to D.Count-1 do begin
Add(TJSONObject(D).Names[i],TJSONObject(D).Items[i]);
end;
except
FreeAndNil(P);
exit;
end;
FreeAndNil(P);
result:=true;
end;
end.
метод Parse(s:String) возвращает false в случае ошибки
метод ifExistKey(key:String) проверяет есть ли узел с указанным ключом на главном уровне.
Использую примерно так:
var
JS:TJSON;
fd:THandle;
filename:string;
Buffer:String;
begin
filename:=IncludeTrailingBackslash(ExtractFileDir(ParamStrUTF8(0)))+'test.json';
fd:=FileOpenUTF8(filename, fmOpenRead);
SetLength(Buffer,FileSize(filename));
FileRead(fd,Buffer[1],Length(Buffer));
FileClose(fd);
JS:=TJSON.Create;
JS.Parse(Buffer);
ShowMessage(JS.FormatJSON); // чтобы посмотреть что там у нас
end;
Краткое описание класса TJSONObject.
FormatJSON:String // выводит в строку всю структуру JSON
Find(Const AName : String) : TJSONData; // находит указанный узел по имени ключа
Get(Const AName : String) ???? // возвращает данные по ключу. функций много, по количеству возвращаемых типов. Смотрите справку.
Clear; // очистка
Add // опять же много функций, для каждого типа своя.
Delete(ключ или индекс) // удаляет узел
свойство Names[Index : Integer] // узнать название узла
свойство Items[Index: Integer]: TJSONData // получить данные узла
свойство Elements[AName: string] : TJSONData // получить данные узла по имени ключа
свойство Objects[AName : String] : TJSONObject // получить данные узла по имени ключа в виде объекта TJSONObject
Ну и конечно же функция Count - количество узлов на главном уровне.
Так вот сходу не найду ссылку на справку, можете посмотреть в самом модуле fpjson, там всё с комментариями.
P.S. Обнаружил ошибку в этом коде. Утечки памяти.
Вот тут исправляю: JSON: Работа над ошибками
P.S. Обнаружил ошибку в этом коде. Утечки памяти.
Вот тут исправляю: JSON: Работа над ошибками
Комментариев нет:
Отправить комментарий