fcl-json
English (en) | русский (ru)
Contents
[hide]Info
fcl-json is a JSON implementation.
It contains units such as:
- fpjson: base unit which implements TJsonData and its children, e.g. TJsonObject
- jsonParser: implements TJsonParser, used in the From JsonViewer example below
- jsonConf: implements TJsonConfig which is handy to read/write application data from/to files
- jsonScanner: json source lexical analyzer
Note: In fpjson, accessing e.g. SomeJSONObject.Integers['price'] may give a SIGSEGV/Access Violation if that integer variable does not exist. This is apparently intentional, see [1]. You'd have to use the Find method (available since FPC 2.6.2) to first check if the element ('price' in this example) exists.
Streaming
fcl-json contains the unit "fpjsonrtti" which is used to load objects (TObject instances) from or save them to JSON format.
See Streaming JSON for a short example.
Examples
Getting Started
uses fpjson, jsonparser; procedure JSONTest; var jData : TJSONData; jObject : TJSONObject; jArray : TJSONArray; s : String; begin // this is only a minimal sampling of what can be done with this API // create from string jData := GetJSON('{"Fld1" : "Hello", "Fld2" : 42, "Colors" : ["Red", "Green", "Blue"]}'); // output as a flat string s := jData.AsJSON; // output as nicely formatted JSON s := jData.FormatJSON; // cast as TJSONObject to make access easier jObject := TJSONObject(jData); // retrieve value of Fld1 s := jObject.Get('Fld1'); // change value of Fld2 jObject.Integers['Fld2'] := 123; // retrieve the second color s := jData.FindPath('Colors[1]').AsString; // add a new element jObject.Add('Happy', True); // add a new sub-array jArray := TJSONArray.Create; jArray.Add('North'); jArray.Add('South'); jArray.Add('East'); jArray.Add('West'); jObject.Add('Directions', jArray); end;
Traversing Items
uses Classes, TypInfo, fpjson, jsonparser; procedure JSONItems(Info: TStrings); var jData : TJSONData; jItem : TJSONData; i, j: Integer; object_name, field_name, field_value, object_type, object_items: String; begin jData := GetJSON('{"A":{"field1":0, "field2": false},"B":{"field1":0, "field2": false}}'); for i := 0 to jData.Count - 1 do begin jItem := jData.Items[i]; object_type := GetEnumName(TypeInfo(TJSONtype), Ord(jItem.JSONType)); object_name := TJSONObject(jData).Names[i]; WriteStr(object_items, jItem.Count); Info.Append('object type: ' + object_type + '|object name: ' + object_name + '|number of fields: ' + object_items); for j := 0 to jItem.Count - 1 do begin field_name := TJSONObject(jItem).Names[j]; field_value := jItem.FindPath(TJSONObject(jItem).Names[j]).AsString; Info.Append(field_name + '|' + field_value); end; end; jData.Free; end;
Save/load dialog position/size
uses jsonConf; procedure TfmMain.SaveOptionsPos; var c: TJSONConfig; begin c:= TJSONConfig.Create(Nil); try c.Filename:= GetAppPath(cFileHistory); c.SetValue('/dialog/max', WindowState=wsMaximized); if WindowState<>wsMaximized then begin c.SetValue('/dialog/posx', Left); c.SetValue('/dialog/posy', Top); c.SetValue('/dialog/sizex', Width); c.SetValue('/dialog/sizey', Height); end; finally c.Free; end; end; procedure TfmMain.LoadOptionsPos; var nLeft, nTop, nW, nH: Integer; c: TJSONConfig; begin c:= TJSONConfig.Create(Nil); try c.Filename:= GetAppPath(cFileHistory); nLeft:= c.GetValue('/dialog/posx', Left); nTop:= c.GetValue('/dialog/posy', Top); nW:= c.GetValue('/dialog/sizex', Width); nH:= c.GetValue('/dialog/sizey', Height); SetBounds(nLeft, nTop, nW, nH); if c.GetValue('/dialog/max', false) then WindowState:= wsMaximized; finally c.Free; end; end;
Save/load TStringList
//Example of path: '/list_find' procedure SLoadStringsFromFile(cfg: TJsonConfig; const path: String; List: TStrings); var i: Integer; s: UnicodeString; begin List.Clear; for i:= 0 to OptMaxHistoryItems-1 do begin s:= cfg.GetValue(path+'/'+inttostr(i), ''); if s='' then Break; List.Add(Utf8Encode(s)); end; end; procedure SSaveStringsToFile(cfg: TJsonConfig; const path: String; List: TStrings); var i: Integer; s: String; begin for i:= 0 to OptMaxHistoryItems-1 do begin if i<List.Count then s:= List[i] else s:= ''; cfg.SetDeleteValue(path+'/'+inttostr(i), Utf8Decode(s), ''); end; end;
From JsonViewer
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:
procedure TMainForm.OpenFile(Const AFileName : String); var S : TFileStream; P : TJSONParser; D : TJSONData; begin S:=TFileStream.Create(AFileName,fmOpenRead); try P:=TJSONParser.Create(S); try P.Strict:=FStrict; D:=P.Parse; finally P.Free; end; finally S.Free; end; FFileName:=AFileName; SetCaption; FreeAndNil(FRoot); FRoot:=D; ShowJSONDocument; end; procedure TMainForm.ShowJSONDocument; begin with TVJSON.Items do begin BeginUpdate; try TVJSON.Items.Clear; SHowJSONData(Nil,FRoot); with TVJSON do if (Items.Count>0) and Assigned(Items[0]) then begin Items[0].Expand(False); Selected:=Items[0]; end; finally EndUpdate; end; end; end; procedure TMainForm.ShowJSONData(AParent : TTreeNode; Data : TJSONData); var N,N2 : TTreeNode; I : Integer; D : TJSONData; C : String; S : TStringList; begin N:=Nil; if Assigned(Data) then begin case Data.JSONType of jtArray, jtObject: begin if (Data.JSONType=jtArray) then C:=SArray else C:=SObject; N:=TVJSON.Items.AddChild(AParent,Format(C,[Data.Count])); S:=TstringList.Create; try for I:=0 to Data.Count-1 do if Data.JSONtype=jtArray then S.AddObject(IntToStr(I),Data.items[i]) else S.AddObject(TJSONObject(Data).Names[i],Data.items[i]); if FSortObjectMembers and (Data.JSONType=jtObject) then S.Sort; for I:=0 to S.Count-1 do begin N2:=TVJSON.Items.AddChild(N,S[i]); D:=TJSONData(S.Objects[i]); N2.ImageIndex:=ImageTypeMap[D.JSONType]; N2.SelectedIndex:=ImageTypeMap[D.JSONType]; ShowJSONData(N2,D); end finally S.Free; end; end; jtNull: N:=TVJSON.Items.AddChild(AParent,SNull); else N:=TVJSON.Items.AddChild(AParent,Data.AsString); end; if Assigned(N) then begin N.ImageIndex:=ImageTypeMap[Data.JSONType]; N.SelectedIndex:=ImageTypeMap[Data.JSONType]; N.Data:=Data; end; end; end;
'언어 > Lazarus' 카테고리의 다른 글
Linux-arm cross compiler for original Raspberry Pi ARMV6Z and FPV2 #148 (0) | 2021.01.07 |
---|---|
라즈베리파이 bass 설치 (0) | 2018.09.03 |
리눅스 파스칼 (lazarus)에서의 home 폴더 지정에 관한 문제점 해결방안 (0) | 2018.09.03 |
SQLite3을 설치하는 방법 (0) | 2018.08.27 |
라즈베리파이에 라자루스 개발환경 만들기 (0) | 2017.12.17 |