Difference between revisions of "Streaming JSON/ru"
m (Fixed syntax highlighting) |
|||
Line 11: | Line 11: | ||
В связи с этим оператор USES должен содержать, по крайней мере, эти два юнита: | В связи с этим оператор USES должен содержать, по крайней мере, эти два юнита: | ||
− | <syntaxhighlight lang=" | + | <syntaxhighlight lang="pascal">USES Classes, fpjsonrtti;</syntaxhighlight> |
В настоящее время (май 2014 г.) есть некоторые отличия от потоковой системы Free Pascal с ??_предположительно_ JavaScript ??: | В настоящее время (май 2014 г.) есть некоторые отличия от потоковой системы Free Pascal с ??_предположительно_ JavaScript ??: | ||
Line 32: | Line 32: | ||
Это может быть выполнено в Free Pascal с использованием констант следующим образом: | Это может быть выполнено в Free Pascal с использованием констант следующим образом: | ||
− | <syntaxhighlight lang=" | + | |
+ | <syntaxhighlight lang="pascal"> | ||
const JSON_TESTDATA = | const JSON_TESTDATA = | ||
'{'+LineEnding+ | '{'+LineEnding+ | ||
Line 44: | Line 45: | ||
== Структура данных == | == Структура данных == | ||
− | В качестве базового класса для обслуживания данных существует класс [[TPersistent]] из юнита Classes, так как для них и всех подклассов должен быть создан [[Runtime Type Information (RTTI)|Laufzeit-Typinformationen]] (<abbr title="Runtime Type Information">RTTI</abbr>). Это совершенно необходимо для маршаллинга. Поскольку fpjsonrtti не интегрирован в систему маршаллинга, любого другого класса, должна быть указана опция компилятора | + | В качестве базового класса для обслуживания данных существует класс [[TPersistent]] из юнита Classes, так как для них и всех подклассов должен быть создан [[Runtime Type Information (RTTI)|Laufzeit-Typinformationen]] (<abbr title="Runtime Type Information">RTTI</abbr>). Это совершенно необходимо для маршаллинга. Поскольку fpjsonrtti не интегрирован в систему маршаллинга, любого другого класса, должна быть указана опция компилятора '''{$M+}''', для использования. |
Все объекты должны быть доступны как [[Property|property]] для чтения в разделе класса [[Published|published]]. В общем случае (переменная) должна быть доступна для чтения и записи непосредственно в поле данных. Если вы хотите, конечно, могут быть использованы методы getter и setter. | Все объекты должны быть доступны как [[Property|property]] для чтения в разделе класса [[Published|published]]. В общем случае (переменная) должна быть доступна для чтения и записи непосредственно в поле данных. Если вы хотите, конечно, могут быть использованы методы getter и setter. | ||
Line 76: | Line 77: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Класс < | + | Класс <syntaxhighlight enclose="none" lang=pascal>TNameObject</source> является потомком [[TCollectionItem]]. Таким образом, они могут оба для свойства ''obj'' использовать коллекции. Если это не желательно, здесь должны быть определены два различных класса. |
В конструкторе класса TBaseObject класс TCollection и список строк должен быть создан конструктором и уничтожен в деструкторе. | В конструкторе класса TBaseObject класс TCollection и список строк должен быть создан конструктором и уничтожен в деструкторе. | ||
Line 103: | Line 104: | ||
== Загрузка JSON == | == Загрузка JSON == | ||
− | С помощью метода < | + | С помощью метода <syntaxhighlight enclose="none" lang=pascal>PROCEDURE JSONToObject(Const JSON : TJSONStringType; AObject : TObject);</source> в классе [[TJSONDeStreamer]] вы можете присвоить данные в формате JSON непосредственно ''существующему'' объекту; перед тем, как вызвать этот метод, вы должны создать TJSONDeStreamer и целевой объект. |
− | Следующий метод загружает данные из структуры JSON < | + | Следующий метод загружает данные из структуры JSON <syntaxhighlight enclose="none" lang=pascal>JSON_TESTDATA</source> в объект "о" и затем выводит текущие значения свойств в консоли. |
− | <syntaxhighlight lang=" | + | <syntaxhighlight lang="pascal"> |
PROCEDURE DeStreamTest; | PROCEDURE DeStreamTest; | ||
VAR | VAR | ||
Line 145: | Line 146: | ||
== Сохранение JSON == | == Сохранение JSON == | ||
− | Для преобразования объекта в текст JSON, используется класс [[TJSONStreamer]]. Здесь используется метод <syntaxhighlight enclose="none"> FUNCTION ObjectToJSONString(AObject : TObject) : TJSONStringType;</syntaxhighlight>. | + | Для преобразования объекта в текст JSON, используется класс [[TJSONStreamer]]. Здесь используется метод <syntaxhighlight enclose="none" lang=pascal> FUNCTION ObjectToJSONString(AObject : TObject) : TJSONStringType;</syntaxhighlight>. |
В следующей процедуре, объект создается, заполняется данными теста, а затем преобразуются в формат JSON. Порядок, в котором сохраняются свойства не могут зависеть от программиста. | В следующей процедуре, объект создается, заполняется данными теста, а затем преобразуются в формат JSON. Порядок, в котором сохраняются свойства не могут зависеть от программиста. |
Revision as of 01:46, 28 February 2020
│
Deutsch (de) │
English (en) │
polski (pl) │
русский (ru) │
中文(中国大陆) (zh_CN) │
JSON(JavaScript Object Notation) является текстовым, стандартизированным форматом данных. Как следует из названия, JSON документы являются правильным кодом JavaScript, где они могут быть непосредственно преобразованы в объекты JavaScript. Но сам по себе JSON может быть использован независимо от используемого языка программирования для обмена данными.
В этом руководстве объясняется, как загрузить данные в формате JSON в программе Free Pascal для обработки. Оно также объясняет, как преобразовать данные FPC в формате JSON (например, чтобы отправить их на веб-сервер).
Общие положения и условия
Загрузка и хранение (маршалинг) FPC данных объекта осуществляется с помощью юнита "fpjsonrtti". Кроме того, может пригодиться класс Class в этом юните (см ниже).
В связи с этим оператор USES должен содержать, по крайней мере, эти два юнита:
USES Classes, fpjsonrtti;
В настоящее время (май 2014 г.) есть некоторые отличия от потоковой системы Free Pascal с ??_предположительно_ JavaScript ??:
- Данные в формате JSON чувствительны к регистру. Таким образом, свойства объектов Free Pascal, как свойства JSON должны быть написаны с правильным регистром.
- Нет свойств, которые могут быть определены как DefineProperties. Нельзя сохранить ссылки на методы (обработчики событий).2
- TCollection и TStrings может быть использован в качестве замены массивов.
Демо-версия программы предоставляется с исходным кодом Free Pascal Compiler (в папке /packages/fcl-json/examples).
В качестве примера, мы приведём пример со следующими данными JSON:
{
"id" : 123, // Integer
"obj" : { "name": "Привет, мир!" }, // Object
"coll" : [ { "name": "Объект 1" }, { "name": "Объект 2" } ], // два объекта TCollection
"strings": [ "привет 1", "привет 2" ] // список строк
}
Это может быть выполнено в Free Pascal с использованием констант следующим образом:
const JSON_TESTDATA =
'{'+LineEnding+
' "id": 123,'+LineEnding+
' "obj": { "name": "Привет, Мир!" },'+LineEnding+
' "coll": [ { "name": "Объект 1" }, { "name": "Объект 2" } ],'+LineEnding+
' "strings": [ "привет 1", "привет 2" ]'+LineEnding+
'}';
Структура данных
В качестве базового класса для обслуживания данных существует класс TPersistent из юнита Classes, так как для них и всех подклассов должен быть создан Laufzeit-Typinformationen (RTTI). Это совершенно необходимо для маршаллинга. Поскольку fpjsonrtti не интегрирован в систему маршаллинга, любого другого класса, должна быть указана опция компилятора {$M+}, для использования.
Все объекты должны быть доступны как property для чтения в разделе класса published. В общем случае (переменная) должна быть доступна для чтения и записи непосредственно в поле данных. Если вы хотите, конечно, могут быть использованы методы getter и setter.
Для структуры JSON результаты определении класса представлены ниже.
TYPE
TNameObject = CLASS(TCollectionItem) // класс для свойства 'obj' и TCollection
PRIVATE
fName: String;
PUBLISHED
property name: String read fName write fName;
END;
TBaseObject = CLASS(TPersistent) // класс для структуры JSON
PRIVATE
fid: Integer;
fObj: TNameObject;
fColl: TCollection;
fStrings: TStrings;
PUBLIC
CONSTRUCTOR Create;
DESTRUCTOR Destroy; override;
PUBLISHED// все свойства должны быть published
PROPERTY id: Integer read fid write fid;
PROPERTY obj: TNameObject read fObj write fObj;
PROPERTY coll: TCollection read fColl;
PROPERTY strings: TStrings read fStrings;
END;
Класс TNameObject</source> является потомком [[TCollectionItem]]. Таким образом, они могут оба для свойства ''obj'' использовать коллекции. Если это не желательно, здесь должны быть определены два различных класса. В конструкторе класса TBaseObject класс TCollection и список строк должен быть создан конструктором и уничтожен в деструкторе. <syntaxhighlight lang="Pascal"> CONSTRUCTOR TBaseObject.Create; BEGIN // конструктор коллекции и StringList fColl := TCollection.Create(TNameObject); fStrings := TStringList.Create; fObj := TNameObject.Create(nil); END; DESTRUCTOR TBaseObject.Destroy; BEGIN // деструктор коллекции и StringList fColl.Free; fStrings.Free; fObj.Free; INHERITED Destroy; END;
Если вы не хотите больше функций для данных классов, их определение закончено.
Загрузка JSON
С помощью метода PROCEDURE JSONToObject(Const JSON : TJSONStringType; AObject : TObject);</source> в классе [[TJSONDeStreamer]] вы можете присвоить данные в формате JSON непосредственно ''существующему'' объекту; перед тем, как вызвать этот метод, вы должны создать TJSONDeStreamer и целевой объект. Следующий метод загружает данные из структуры JSON <syntaxhighlight enclose="none" lang=pascal>JSON_TESTDATA</source> в объект "о" и затем выводит текущие значения свойств в консоли. <syntaxhighlight lang="pascal"> PROCEDURE DeStreamTest; VAR DeStreamer: TJSONDeStreamer; o: TBaseObject; no: TNameObject; s: String; BEGIN WriteLn('тест DeStream'); WriteLn('======================================'); // объект DeStreamer и целевой объект DeStreamer := TJSONDeStreamer.Create(nil); o := TBaseObject.Create; TRY // загрузка данных JSON в объект o DeStreamer.JSONToObject(JSON_TESTDATA, o); // ID WriteLn(o.id); // имя объекта WriteLn(o.obj.name); // напечатать имена всех объектов for TCollectionItem(no) in o.coll do Writeln(no.name); // вывести все строки for s in o.strings do WriteLn(s); // очистка FINALLY o.Destroy; DeStreamer.Destroy; END; END;
Сохранение JSON
Для преобразования объекта в текст JSON, используется класс TJSONStreamer. Здесь используется метод FUNCTION ObjectToJSONString(AObject : TObject) : TJSONStringType;
.
В следующей процедуре, объект создается, заполняется данными теста, а затем преобразуются в формат JSON. Порядок, в котором сохраняются свойства не могут зависеть от программиста.
И, наконец, текст JSON выводится на консоль.
PROCEDURE StreamTest;
VAR
Streamer: TJSONStreamer;
o: TBaseObject;
JSONString: String;
BEGIN
WriteLn('Stream test');
WriteLn('======================================');
Streamer := TJSONStreamer.Create(nil);
o := TBaseObject.Create;
TRY
// установка данных
o.id := 123;
o.obj.name := 'Привет, мир!';
TNameObject(o.coll.Add).name := 'Объект 1';
TNameObject(o.coll.Add).name := 'Объект 2';
o.strings.Add('Привет 1');
o.strings.Add('Привет 2');
Streamer.Options := Streamer.Options + [jsoTStringsAsArray]; // сохранение строки в JSON
// конвертация вывод и JSON
JSONString := Streamer.ObjectToJSONString(o);
WriteLn(JSONString);
// очистка
FINALLY
o.Destroy;
Streamer.Destroy;
END;
END;
Вывод
С помощью представленного знания, простые и сложные структуры данных JSON могут быть загружены в ваши программы на Free Pascal. Если необходима какая-либо пред- или постобработка данных JSON, текстовые данные могут быть изначально загружены в структуру данных в формате JSON (классом TJSONParser из юнита jsonparser), а затем можно обрабатывать с помощью юнита fpJSON.
Опции свойства TJSONStreamer могут быть использованы для управления представлением ваших собственных структур данных в формате JSON.