fcl-json/pl

From Free Pascal wiki
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

English (en) polski (pl) русский (ru) 中文(中国大陆)‎ (zh_CN)

Informacje

fcl-json jest implementacją JSON.

Zawiera moduły takie jak:

  • fpjson: moduł podstawowy, który implementuje TJsonData i jego klasy potomne, np. TJsonObject
  • jsonParser: implementuje parser TJsonParser, użyty w przykładzie z JsonViewer poniżej
  • jsonConf: implementuje TJsonConfig, który jest przydatny do odczytu/zapisu danych aplikacji z/do plików
  • jsonScanner: leksykalny analizator źródła JSON
Light bulb  Uwaga: W fpjson dostęp np. do SomeJSONObject.Integers['price'] może wywołać zdarzenie SIGSEGV/Access Violation (naruszenie dostępu), jeśli ta zmienna Integers nie istnieje. Jest to pozornie celowe, patrz [[1]]. Będziesz musiał użyć metody Find (dostępnej od wersji FPC 2.6.2), aby najpierw sprawdzić, czy element ('price' w tym przykładzie) istnieje.

Przesyłanie strumieniowe

fcl-json zawiera moduł "fpjsonrtti", który służy do ładowania obiektów (instancji TObject) z formatu JSON lub do zapisywania ich w formacie JSON.

Zobacz Streaming JSON na krótkim przykładzie.

Przykłady

Pierwsze kroki

uses
  fpjson, jsonparser;

procedure JSONTest;
var
  jData : TJSONData;
  jObject : TJSONObject;
  jArray : TJSONArray;
  s : String;
begin
  
  // jest to tylko minimalna próbka tego, co można zrobić z tym interfejsem API

  // utwórz z ciągu string
  jData := GetJSON('{"Fld1" : "Hello", "Fld2" : 42, "Colors" : ["Red", "Green", "Blue"]}');

  // wyjście jako płaski ciąg string
  s := jData.AsJSON;

  // wyjście jest ładnie sformatowanym JSON
  s := jData.FormatJSON;

  // rzutowanie jako TJSONObject, aby ułatwić dostęp
  jObject := TJSONObject(jData);

  // pobierz wartość Fld1
  s := jObject.Get('Fld1');

  // zmień wartość Fld2
  jObject.Integers['Fld2'] := 123;

  // pobierz drugi kolor
  s := jData.FindPath('Colors[1]').AsString;

  // dodaj nowy element
  jObject.Add('Happy', True);

  // dodaj nową pod-tablicę
  jArray := TJSONArray.Create;
  jArray.Add('North');
  jArray.Add('South');
  jArray.Add('East');
  jArray.Add('West');
  jObject.Add('Directions', jArray);

end;

Przenoszenie elementów

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;

Zapisz/wczytaj pozycję/rozmiar okna dialogowego

uses
  jsonConf;

procedure TfmMain.SaveOptionsPos;
var
  c: TJSONConfig;
begin
  c:= TJSONConfig.Create(Nil);
  try
    c.Filename:= 'form.cfg';
    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:= 'form.cfg';

    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;

W pliku form.cf zapisze się struktura JSON podobna do tej: { "dialog" : { "max" : false, "posx" : 141, "posy" : 247, "sizex" : 320, "sizey" : 240 } }

Zapisz/wczytaj TStringList

//Przykład ścieżki: '/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;

Przykład z JsonViewer

Przykład użycia można znaleźć w narzędziu Lazarus jsonviewer (znajdującym się w lazarus/tools/jsonviewer). W szczególności, ta część narzędzia pokazuje, jak używać 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;

FpcTwit

Biblioteka Przykłady komponentów i kodu wykorzystuje JSON do wysyłania/odbierania danych.

Zobacz też