Sign in Join
Wiki copytemporary

Streaming JSON/pl: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Streaming JSON/pl

OldNewLine
1+[[JSON/pl|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.
2+
3+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).
4+
5+## Ogólne wymagania
6+
7+Ł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).
8+
9+Instrukcja użycia powinna zatem zawierać przynajmniej te dwa moduły:
10+
11+``` pascal
12+uses Classes, fpjsonrtti;
13+```
14+
15+Obecnie (maj 2014) istnieją pewne różnice między systemem przesyłania strumieniowego Free Pascala a JSON:
16+
17+- 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.
18+- 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
19+- [[TCollection/pl|TCollection]] i [[TStrings]] mogą być stosowane jako zamienniki tablic.
20+
21+Programy demonstracyjne wraz z kodem źródłowym kompilatora Free Pascal znajdują się w katalogu `packages/fcl-json/examples`.
22+
23+Taka jak poniżej struktura JSON, jest używana w dalszych przykładach:
24+
25+``` JavaScript
26+{
27+ "id" : 123, // liczba całkowita (integer)
28+ "obj" : { "name": "Witaj Świecie!" }, // jakiś obiekt
29+ "coll" : [ { "name": "Obiekt 1" }, { "name": "Obiekt 2" } ], // dwa obiekty w TCollection
30+ "strings": [ "Witaj 1", "Witaj 2" ] // ciągi znaków
31+}
32+```
33+
34+Można ją zdefiniować w programie Free Pascal jako wartość stałą w następujący sposób:
35+
36+``` pascal
37+const JSON_TESTDATA =
38+'{'+LineEnding+
39+' "id": 123,'+LineEnding+
40+' "obj": { "name": "Witaj Świecie!" },'+LineEnding+
41+' "coll": [ { "name": "Obiekt 1" }, { "name": "Obiekt 2" } ],'+LineEnding+
42+' "strings": [ "Witaj 1", "Witaj 2" ]'+LineEnding+
43+'}';
44+```
45+
46+## Struktura danych
47+
48+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+}**.
49+
50+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.
51+
52+Poniższa definicja klasy wynika ze struktury JSON:
53+
54+``` pascal
55+type
56+ TNameObject = class(TCollectionItem) // klasa dla właściwości 'obj' typu TCollection
57+ private
58+ fName: String;
59+ published
60+ property name: String read fName write fName;
61+ end;
62+
63+ TBaseObject = class(TPersistent) // klasa dla całej struktury JSON
64+ private
65+ fid: Integer;
66+ fObj: TNameObject;
67+ fColl: TCollection;
68+ fStrings: TStrings;
69+ public
70+ constructor Create;
71+ destructor Destroy; override;
72+ published // wszystkie właściwości muszą mieć prawa dostępu published
73+ property id: Integer read fid write fid;
74+ property obj: TNameObject read fObj write fObj;
75+ property coll: TCollection read fColl;
76+ property strings: TStrings read fStrings;
77+ end;
78+```
79+
80+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.
81+
82+TCollection i TStrings muszą zostać utworzone w konstruktorze klasy TBaseObject i zwolnione w destruktorze.
83+
84+``` pascal
85+constructor TBaseObject.Create;
86+begin
87+ // Utwórz kolekcję i listę ciągów
88+ fColl := TCollection.Create(TNameObject);
89+ fStrings := TStringList.Create;
90+ fObj := TNameObject.Create(nil);
91+end;
92+
93+destructor TBaseObject.Destroy;
94+begin
95+ // Zwolnij kolekcję i listę ciągów
96+ fColl.Free;
97+ fStrings.Free;
98+ fObj.Free;
99+ inherited Destroy;
100+end;
101+```
102+
103+Jeśli nie chcesz mieć więcej funkcji w klasach danych, ich definicja jest teraz kompletna.
104+
105+## Załaduj JSON
106+
107+Za pomocą metody `Procedure JSONToObject(Const JSON : TJSONStringType; AObject : TObject);` w klasie [[TJSONDeStreamer]] można przypisać dane JSON bezpośrednio do istniejącego obiektu. Przed wywołaniem metody należy utworzyć TJSONDeStreamer i obiekt docelowy.
108+
109+Poniższa metoda ładuje dane ze struktury JSON `JSON_TESTDATA` w obiekcie o, a następnie wypisuje bieżące wartości właściwości do konsoli.
110+
111+``` pascal
112+procedure DeStreamTest;
113+var
114+ DeStreamer: TJSONDeStreamer;
115+ o: TBaseObject;
116+ no: TNameObject;
117+ s: String;
118+begin
119+ WriteLn('DeStream test');
120+ WriteLn('======================================');
121+
122+ // Utwórz obiekt DeStreamer i obiekt docelowy
123+ DeStreamer := TJSONDeStreamer.Create(nil);
124+ o := TBaseObject.Create;
125+ try
126+ // Załaduj dane JSON do obiektu o
127+ DeStreamer.JSONToObject(JSON_TESTDATA, o);
128+ // wypisz ID
129+ WriteLn(o.id);
130+ // wypisz nazwę obiektu
131+ WriteLn(o.obj.name);
132+ // wypisz nazwy wszystkich obiektów
133+ for TCollectionItem(no) in o.coll do
134+ Writeln(no.name);
135+ // wypisz wszystkie ciągi
136+ for s in o.strings do
137+ WriteLn(s);
138+
139+ // Czyszczenie
140+ finally
141+ o.Destroy;
142+ DeStreamer.Destroy;
143+ end;
144+end;
145+```
146+
147+## Zapisywanie JSON
148+
149+Klasa [[TJSONStreamer]] służy do konwersji obiektu na tekstowy JSON. Tutaj używana jest metoda `Function ObjectToJSONString(AObject : TObject) : TJSONStringType;`.
150+
151+W poniższej procedurze tworzony jest obiekt, wypełniany danymi testowymi, a następnie konwertowany na JSON. Tekst JSON jest wyprowadzany na konsolę. Kolejność, w jakiej właściwości są wyprowadzane, nie może zostać określona.
152+
153+``` pascal
154+procedure StreamTest;
155+var
156+ Streamer: TJSONStreamer;
157+ o: TBaseObject;
158+ JSONString: String;
159+begin
160+ WriteLn('Stream test');
161+ WriteLn('======================================');
162+
163+ Streamer := TJSONStreamer.Create(nil);
164+ o := TBaseObject.Create;
165+ try
166+ // Skonfiguruj dane
167+ o.id := 123;
168+ o.obj.name := 'Witaj Świecie!';
169+ TNameObject(o.coll.Add).name := 'Obiekt 1';
170+ TNameObject(o.coll.Add).name := 'Obiekt 2';
171+ o.strings.Add('Witaj 1');
172+ o.strings.Add('Witaj 2');
173+
174+ Streamer.Options := Streamer.Options + [jsoTStringsAsArray]; // Zapisz ciągi jako tablicę JSON
175+ // konwersja do JSON i na wyjście konsoli
176+ JSONString := Streamer.ObjectToJSONString(o);
177+ WriteLn(JSONString);
178+
179+ // Czyszczenie
180+ finally
181+ o.Destroy;
182+ Streamer.Destroy;
183+ end;
184+end;
185+```
186+
187+## Wnioski
188+
189+Dzięki przedstawionej tu wiedzy, proste i złożone struktury danych JSON można załadować do programów Free Pascal. Jeśli konieczne będzie jakiekolwiek wstępne lub końcowe przetwarzanie danych JSON, dane tekstowe można najpierw załadować z modułu [[jsonparser]] do struktury danych JSON przy użyciu klasy [[TJSONParser]], a następnie odpowiednio manipulować za pomocą modułu [[fpJSON]].
190+
191+Za pomocą właściwości Options klasy TJSONStreamer można kontrolować, w jaki sposób dane wyjściowe mapują własne struktury danych w JSON.
192+
193+## Zobacz także
194+
195+- [[JSON/pl|JSON]]
196+- [[fcl-json/pl|fcl-json]]
197+- [[Streaming components/pl|Komponenty strumieniowe]]
198+
199+## Uwagi i referencje
200+
201+1. <div id="ref1">
202+
203+ <http://lists.freepascal.org/fpc-pascal/2013-January/036254.html>
204+
205+ </div>
206+
207+2. \<div id="ref2\>http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-January/058878.html
208+ </div>
209+
210+---
211+*From the Free Pascal wiki, page "Streaming JSON/pl", as it stood on 2023-01-31 after a change by Slawek, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history