Sign in Join
Wiki copytemporary

fcl-json/zh CN: what changed

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

Title: fcl-json/zh CN

OldNewLine
1+# 信息
2+
3+fcl-json 是一个 [[JSON]] 的实现.
4+
5+它包含如下单元:
6+
7+- fpjson: 实现 TJsonData 及其子项的基本单元, e.g. TJsonObject
8+- jsonParser: 实现 TJsonParser, 被用在下面的 从 JsonViewer 示例
9+- jsonConf: 实现 TJsonConfig 可以方便地从文件读取/写入应用程序数据
10+- jsonScanner: json源码词法分析器
11+
12+注: 在 fpjson, 访问形如 SomeJSONObject.Integers\['price'\] 可能给出一个 SIGSEGV/Access 冲突 如果这个Integer型变量不存在. 这显然是故意的, 看 [1](http://bugs.freepascal.org/view.php?id=22273). 你必须使用Find方法 (FPC 2.6.2以上可用) 来检查元素 ('price' 在例子中) 是否存在.
13+
14+# 流
15+
16+fcl-json 包含单元“fpjsonrtti”,用于从 JSON 格式加载对象(TObject 实例)或将其保存为 JSON 格式。
17+
18+简短的示例,请看 [[Streaming JSON]] .
19+
20+# 例子
21+
22+## 入门
23+
24+``` pascal
25+uses
26+ fpjson, jsonparser;
27+
28+procedure JSONTest;
29+var
30+ jData : TJSONData;
31+ jObject : TJSONObject;
32+ jArray : TJSONArray;
33+ s : String;
34+begin
35+ // 这只是使用此 API 可以完成的最小示例
36+
37+ // 从字符串创建
38+ jData := GetJSON('{"Fld1" : "Hello", "Fld2" : 42, "Colors" : ["Red", "Green", "Blue"]}');
39+
40+ // 输出格式化的字符串
41+ s := jData.AsJSON;
42+
43+ // 输出格式良好的 JSON
44+ s := jData.FormatJSON;
45+
46+ // 转换为 TJSONObject 以使访问更容易
47+ jObject := jData as TJSONObject;
48+
49+ // 检索 Fld1 的值
50+ s := jObject.Get('Fld1');
51+
52+ // 修改 Fld2 的值
53+ jObject.Integers['Fld2'] := 123;
54+
55+ // 检索第二个颜色
56+ s := jData.FindPath('Colors[1]').AsString;
57+
58+ // 新增一个元素
59+ jObject.Add('Happy', True);
60+
61+ // 新增一个子数组
62+ jArray := TJSONArray.Create;
63+ jArray.Add('North');
64+ jArray.Add('South');
65+ jArray.Add('East');
66+ jArray.Add('West');
67+ jObject.Add('Directions', jArray);
68+
69+end;
70+```
71+
72+注: 当你使用jData完毕,将它释放时必要的. 否则一个内存泄漏会被制造.
73+
74+## 遍历项目
75+
76+``` pascal
77+uses
78+ Classes, TypInfo, fpjson, jsonparser;
79+
80+procedure JSONItems(Info: TStrings);
81+var
82+ jData : TJSONData;
83+ jItem : TJSONData;
84+ i, j: Integer;
85+ object_name, field_name, field_value, object_type, object_items: String;
86+begin
87+ jData := GetJSON('{"A":{"field1":0, "field2": false},"B":{"field1":0, "field2": false}}');
88+
89+ for i := 0 to jData.Count - 1 do
90+ begin
91+ jItem := jData.Items[i];
92+
93+ object_type := GetEnumName(TypeInfo(TJSONtype), Ord(jItem.JSONType));
94+ object_name := TJSONObject(jData).Names[i];
95+ WriteStr(object_items, jItem.Count);
96+
97+ Info.Append('object type: ' + object_type + '|object name: ' + object_name + '|number of fields: ' + object_items);
98+
99+ for j := 0 to jItem.Count - 1 do
100+ begin
101+ field_name := TJSONObject(jItem).Names[j];
102+ field_value := jItem.FindPath(TJSONObject(jItem).Names[j]).AsString;
103+
104+ Info.Append(field_name + '|' + field_value);
105+ end;
106+ end;
107+
108+ jData.Free;
109+end;
110+```
111+
112+## 保存/加载对话框位置/大小
113+
114+``` pascal
115+uses
116+ jsonConf;
117+
118+procedure TfmMain.SaveOptionsPos;
119+var
120+ c: TJSONConfig;
121+begin
122+ c:= TJSONConfig.Create(Nil);
123+ try
124+ c.Filename:= GetAppPath(cFileHistory);
125+ c.SetValue('/dialog/max', WindowState=wsMaximized);
126+ if WindowState<>wsMaximized then
127+ begin
128+ c.SetValue('/dialog/posx', Left);
129+ c.SetValue('/dialog/posy', Top);
130+ c.SetValue('/dialog/sizex', Width);
131+ c.SetValue('/dialog/sizey', Height);
132+ end;
133+ finally
134+ c.Free;
135+ end;
136+end;
137+
138+procedure TfmMain.LoadOptionsPos;
139+var
140+ nLeft, nTop, nW, nH: Integer;
141+ c: TJSONConfig;
142+begin
143+ c:= TJSONConfig.Create(Nil);
144+ try
145+ c.Filename:= GetAppPath(cFileHistory);
146+
147+ nLeft:= c.GetValue('/dialog/posx', Left);
148+ nTop:= c.GetValue('/dialog/posy', Top);
149+ nW:= c.GetValue('/dialog/sizex', Width);
150+ nH:= c.GetValue('/dialog/sizey', Height);
151+ SetBounds(nLeft, nTop, nW, nH);
152+
153+ if c.GetValue('/dialog/max', false) then
154+ WindowState:= wsMaximized;
155+ finally
156+ c.Free;
157+ end;
158+end;
159+```
160+
161+## 保存/载入 TStringList
162+
163+``` pascal
164+//Example of path: '/list_find'
165+
166+procedure SLoadStringsFromFile(cfg: TJsonConfig; const path: String; List: TStrings);
167+var
168+ i: Integer;
169+ s: UnicodeString;
170+begin
171+ List.Clear;
172+ for i:= 0 to OptMaxHistoryItems-1 do
173+ begin
174+ s:= cfg.GetValue(path+'/'+inttostr(i), '');
175+ if s='' then
176+ Break;
177+ List.Add(Utf8Encode(s));
178+ end;
179+end;
180+
181+procedure SSaveStringsToFile(cfg: TJsonConfig; const path: String; List: TStrings);
182+var
183+ i: Integer;
184+ s: String;
185+begin
186+ for i:= 0 to OptMaxHistoryItems-1 do
187+ begin
188+ if i<List.Count then
189+ s:= List[i]
190+ else
191+ s:= '';
192+ cfg.SetDeleteValue(path+'/'+inttostr(i), Utf8Decode(s), '');
193+ end;
194+end;
195+```
196+
197+## 从 JsonViewer
198+
199+Example usage can be found in the Lazarus jsonviewer tool (located in lazarus/tools/jsonviewer). In particular, this part of the tool shows how to use json:
200+
201+``` pascal
202+procedure TMainForm.OpenFile(Const AFileName : String);
203+var
204+ S : TFileStream;
205+ P : TJSONParser;
206+ D : TJSONData;
207+begin
208+ S:=TFileStream.Create(AFileName,fmOpenRead);
209+ try
210+ P:=TJSONParser.Create(S);
211+ try
212+ P.Strict:=FStrict;
213+ D:=P.Parse;
214+ finally
215+ P.Free;
216+ end;
217+ finally
218+ S.Free;
219+ end;
220+ FFileName:=AFileName;
221+ SetCaption;
222+ FreeAndNil(FRoot);
223+ FRoot:=D;
224+ ShowJSONDocument;
225+end;
226+
227+procedure TMainForm.ShowJSONDocument;
228+begin
229+ with TVJSON.Items do
230+ begin
231+ BeginUpdate;
232+ try
233+ TVJSON.Items.Clear;
234+ SHowJSONData(Nil,FRoot);
235+ with TVJSON do
236+ if (Items.Count>0) and Assigned(Items[0]) then
237+ begin
238+ Items[0].Expand(False);
239+ Selected:=Items[0];
240+ end;
241+ finally
242+ EndUpdate;
243+ end;
244+ end;
245+end;
246+
247+procedure TMainForm.ShowJSONData(AParent : TTreeNode; Data : TJSONData);
248+var
249+ N,N2 : TTreeNode;
250+ I : Integer;
251+ D : TJSONData;
252+ C : String;
253+ S : TStringList;
254+begin
255+ N:=Nil;
256+ if Assigned(Data) then
257+ begin
258+ case Data.JSONType of
259+ jtArray,
260+ jtObject:
261+ begin
262+ if (Data.JSONType=jtArray) then
263+ C:=SArray
264+ else
265+ C:=SObject;
266+ N:=TVJSON.Items.AddChild(AParent,Format(C,[Data.Count]));
267+ S:=TstringList.Create;
268+ try
269+ for I:=0 to Data.Count-1 do
270+ if Data.JSONtype=jtArray then
271+ S.AddObject(IntToStr(I),Data.items[i])
272+ else
273+ S.AddObject(TJSONObject(Data).Names[i],Data.items[i]);
274+ if FSortObjectMembers and (Data.JSONType=jtObject) then
275+ S.Sort;
276+ for I:=0 to S.Count-1 do
277+ begin
278+ N2:=TVJSON.Items.AddChild(N,S[i]);
279+ D:=TJSONData(S.Objects[i]);
280+ N2.ImageIndex:=ImageTypeMap[D.JSONType];
281+ N2.SelectedIndex:=ImageTypeMap[D.JSONType];
282+ ShowJSONData(N2,D);
283+ end
284+ finally
285+ S.Free;
286+ end;
287+ end;
288+ jtNull:
289+ N:=TVJSON.Items.AddChild(AParent,SNull);
290+ else
291+ N:=TVJSON.Items.AddChild(AParent,Data.AsString);
292+ end;
293+ if Assigned(N) then
294+ begin
295+ N.ImageIndex:=ImageTypeMap[Data.JSONType];
296+ N.SelectedIndex:=ImageTypeMap[Data.JSONType];
297+ N.Data:=Data;
298+ end;
299+ end;
300+end;
301+```
302+
303+## 参考
304+
305+- FpcTwit 例子在 [[Components and Code examples]] 库中使用JSON来发送/接受数据.
306+- FCL给fpjson单元的参考 <https://lazarus-ccr.sourceforge.io/fpcdoc/fcl/fpjson/index.html>
307+- 一篇文章覆盖FreePascal中XML和JSON的使用: [PDF](http://www.freepascal.org/~michael/articles/webdata/webdata.pdf)
308+- [[Package List]]
309+
310+---
311+*From the Free Pascal wiki, page "fcl-json/zh CN", as it stood on 2022-05-30 after a change by Iruanp, 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