Difference between revisions of "Streaming JSON/pl"
(→Ogólne wymagania: tłumaczenie na j. polski) |
(→Data Structure: tłumaczenie na j. polski) |
||
Line 46: | Line 46: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | == | + | == Struktura danych == |
− | + | Podstawową klasą danych jest [[TPersistent]] z modułu Classes, ponieważ dla niej i wszystkich podklas tworzona jest [[Runtime Type Information (RTTI)|informacja o typie środowiska wykonawczego (RTTI)]]. Są one niezbędne do przesyłania strumieniowego. Ponieważ fpjsonrtti nie integruje się z systemem przesyłania strumieniowego, można również użyć dowolnej innej klasy przetłumaczonej za pomocą przełącznika kompilatora '''{$M+}'''. | |
− | + | Wszystkie właściwości do odczytu muszą być zadeklarowane w klasie jako [[Property|property]] w sekcji [[Published|published]]. Z reguły można używać odczytu i zapisu w celu odniesienia bezpośrednio do pola danych (zmiennej). Jeśli chcesz, możesz oczywiście użyć metod get i set. | |
− | + | Poniższa definicja klasy wynika ze struktury JSON: | |
<syntaxhighlight lang=pascal> | <syntaxhighlight lang=pascal> | ||
type | type | ||
− | TNameObject = class(TCollectionItem) // | + | TNameObject = class(TCollectionItem) // klasa dla właściwości 'obj' typu TCollection |
private | private | ||
fName: String; | fName: String; | ||
Line 63: | Line 63: | ||
end; | end; | ||
− | TBaseObject = class(TPersistent) // | + | TBaseObject = class(TPersistent) // klasa dla całej struktury JSON |
private | private | ||
fid: Integer; | fid: Integer; | ||
Line 72: | Line 72: | ||
constructor Create; | constructor Create; | ||
destructor Destroy; override; | destructor Destroy; override; | ||
− | published // | + | published // wszystkie właściwości muszą mieć prawa dostępu published |
property id: Integer read fid write fid; | property id: Integer read fid write fid; | ||
property obj: TNameObject read fObj write fObj; | property obj: TNameObject read fObj write fObj; | ||
Line 80: | Line 80: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | Klasa <syntaxhighlight enclose="none" lang=pascal>TNameObject</syntaxhighlight> została odziedziczona z [[TCollectionItem]]. Oznacza to, że można ją używać zarówno dla właściwości obj, jak i dla coll. Jeśli nie jest to pożądane, należy zdefiniować tutaj dwie różne klasy. | |
− | + | TCollection i TStrings muszą zostać utworzone w konstruktorze klasy TBaseObject i zwolnione w destruktorze. | |
<syntaxhighlight lang=pascal> | <syntaxhighlight lang=pascal> | ||
constructor TBaseObject.Create; | constructor TBaseObject.Create; | ||
begin | begin | ||
− | // | + | // Utwórz kolekcję i listę ciągów |
fColl := TCollection.Create(TNameObject); | fColl := TCollection.Create(TNameObject); | ||
fStrings := TStringList.Create; | fStrings := TStringList.Create; | ||
Line 95: | Line 95: | ||
destructor TBaseObject.Destroy; | destructor TBaseObject.Destroy; | ||
begin | begin | ||
− | // | + | // Zwolnij kolekcję i listę ciągów |
fColl.Free; | fColl.Free; | ||
fStrings.Free; | fStrings.Free; | ||
Line 103: | Line 103: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | Jeśli nie chcesz mieć więcej funkcji w klasach danych, ich definicja jest teraz kompletna. | |
== Load JSON == | == Load JSON == |
Revision as of 10:34, 6 June 2020
│
Deutsch (de) │
English (en) │
polski (pl) │
русский (ru) │
中文(中国大陆) (zh_CN) │
JSON (JavaScript Object Notation) to tekstowy, znormalizowany format danych. Jak sama nazwa wskazuje, dokumenty JSON są poprawnym kodem JavaScript i mogą być bezpośrednio konwertowane na obiekty JavaScript. JSON może jednak służyć do wymiany danych niezależnie od używanego języka programowania.
W tym samouczku wyjaśniono, jak ładować dane JSON do programu Free Pascal i jak je w nim przetwarzać. Wyjaśnia także, jak konwertować dane z programu do JSON (np. Aby wysłać je do przeglądarki internetowej).
Ogólne wymagania
Ładowanie i przechowywanie (przesyłanie strumieniowe) obiektów odbywa się za pomocą modułu fpjsonrtti. Ale ma to sens, gdy użyty jest również moduł Classes (szczegóły poniżej).
Instrukcja użycia powinna zatem zawierać przynajmniej te dwa moduły:
uses Classes, fpjsonrtti;
Obecnie (maj 2014) istnieją pewne różnice między systemem przesyłania strumieniowego Free Pascala a JSON:
- JSON to format danych, w którym rozróżniana jest wielkość liter. Wynika z tego, że właściwości obiektów Free Pascal muszą być zapisane w tym samym miejscu, co właściwości JSON.
- Za pomocą DefineProperties nie można zdefiniować żadnych właściwości. Nie można zapisać odwołań do metod (procedur obsługi zdarzeń).2
- TCollection i TStrings mogą być stosowane jako zamienniki tablic.
Programy demonstracyjne wraz z kodem źródłowym kompilatora Free Pascal znajdują się w katalogu packages/fcl-json/examples.
Taka jak poniżej struktura JSON, jest używana w dalszych przykładach:
{
"id" : 123, // liczba całkowita (integer)
"obj" : { "name": "Witaj Świecie!" }, // jakiś obiekt
"coll" : [ { "name": "Obiekt 1" }, { "name": "Obiekt 2" } ], // dwa obiekty w TCollection
"strings": [ "Witaj 1", "Witaj 2" ] // ciągi znaków
}
Można ją zdefiniować w programie Free Pascal jako wartość stałą w następujący sposób:
const JSON_TESTDATA =
'{'+LineEnding+
' "id": 123,'+LineEnding+
' "obj": { "name": "Witaj Świecie!" },'+LineEnding+
' "coll": [ { "name": "Obiekt 1" }, { "name": "Obiekt 2" } ],'+LineEnding+
' "strings": [ "Witaj 1", "Witaj 2" ]'+LineEnding+
'}';
Struktura danych
Podstawową klasą danych jest TPersistent z modułu Classes, ponieważ dla niej i wszystkich podklas tworzona jest informacja o typie środowiska wykonawczego (RTTI). Są one niezbędne do przesyłania strumieniowego. Ponieważ fpjsonrtti nie integruje się z systemem przesyłania strumieniowego, można również użyć dowolnej innej klasy przetłumaczonej za pomocą przełącznika kompilatora {$M+}.
Wszystkie właściwości do odczytu muszą być zadeklarowane w klasie jako property w sekcji published. Z reguły można używać odczytu i zapisu w celu odniesienia bezpośrednio do pola danych (zmiennej). Jeśli chcesz, możesz oczywiście użyć metod get i set.
Poniższa definicja klasy wynika ze struktury JSON:
type
TNameObject = class(TCollectionItem) // klasa dla właściwości 'obj' typu TCollection
private
fName: String;
published
property name: String read fName write fName;
end;
TBaseObject = class(TPersistent) // klasa dla całej struktury JSON
private
fid: Integer;
fObj: TNameObject;
fColl: TCollection;
fStrings: TStrings;
public
constructor Create;
destructor Destroy; override;
published // wszystkie właściwości muszą mieć prawa dostępu 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;
Klasa TNameObject
została odziedziczona z TCollectionItem. Oznacza to, że można ją używać zarówno dla właściwości obj, jak i dla coll. Jeśli nie jest to pożądane, należy zdefiniować tutaj dwie różne klasy.
TCollection i TStrings muszą zostać utworzone w konstruktorze klasy TBaseObject i zwolnione w destruktorze.
constructor TBaseObject.Create;
begin
// Utwórz kolekcję i listę ciągów
fColl := TCollection.Create(TNameObject);
fStrings := TStringList.Create;
fObj := TNameObject.Create(nil);
end;
destructor TBaseObject.Destroy;
begin
// Zwolnij kolekcję i listę ciągów
fColl.Free;
fStrings.Free;
fObj.Free;
inherited Destroy;
end;
Jeśli nie chcesz mieć więcej funkcji w klasach danych, ich definicja jest teraz kompletna.
Load JSON
With the method Procedure JSONToObject(Const JSON : TJSONStringType; AObject : TObject);
in the TJSONDeStreamer class you can assign JSON data directly to an existing object. Before you call the method, you must create TJSONDeStreamer and the target object.
The following method loads the data from the JSON structure JSON_TESTDATA
in the object o and then outputs the current values of the properties to the console.
procedure DeStreamTest;
var
DeStreamer: TJSONDeStreamer;
o: TBaseObject;
no: TNameObject;
s: String;
begin
WriteLn('DeStream test');
WriteLn('======================================');
// Create the DeStreamer object and target object
DeStreamer := TJSONDeStreamer.Create(nil);
o := TBaseObject.Create;
try
// Load JSON data into object o
DeStreamer.JSONToObject(JSON_TESTDATA, o);
// output ID
WriteLn(o.id);
// output object name
WriteLn(o.obj.name);
// output the names of all objects
for TCollectionItem(no) in o.coll do
Writeln(no.name);
// output all strings
for s in o.strings do
WriteLn(s);
// Cleanup
finally
o.Destroy;
DeStreamer.Destroy;
end;
end;
Saving JSON
The class TJSONStreamer is used to convert an object into JSON text. Here the method Function ObjectToJSONString(AObject : TObject) : TJSONStringType;
is used.
In the following procedure, an object is created, filled with the test data, and then converted to JSON. The JSON text is output on the console. The order in which the properties are output cannot be specified.
procedure StreamTest;
var
Streamer: TJSONStreamer;
o: TBaseObject;
JSONString: String;
begin
WriteLn('Stream test');
WriteLn('======================================');
Streamer := TJSONStreamer.Create(nil);
o := TBaseObject.Create;
try
// Setup data
o.id := 123;
o.obj.name := 'Hello world!';
TNameObject(o.coll.Add).name := 'Object 1';
TNameObject(o.coll.Add).name := 'Object 2';
o.strings.Add('Hello 1');
o.strings.Add('Hello 2');
Streamer.Options := Streamer.Options + [jsoTStringsAsArray]; // Save strings as JSON array
// convert to JSON and output to console
JSONString := Streamer.ObjectToJSONString(o);
WriteLn(JSONString);
// Cleanup
finally
o.Destroy;
Streamer.Destroy;
end;
end;
Conclusion
With the knowledge presented, simple and complex JSON data structures can be loaded into Free Pascal programs. Should any pre- or post-processing of the JSON data be necessary, the text data can be first loaded from the jsonparser unit into a JSON data structure using the TJSONParser class and then manipulated as desired with the fpJSON unit.
The Options property of the TJSONStreamer class can be used to control how the output maps its own data structures in JSON.