fcl-json/ru

From Lazarus wiki
Jump to navigationJump to search

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

Информация

fcl-json реализация стандарта JSON.

Пакет содержит юниты:

  • fpjson: базовый юнит, который реализует TJsonData и их потомков, например TJsonObject
  • JsonParser: реализует TJsonParser, используется в примере ниже
  • jsonConf: реализует TJsonConfig, что удобно для чтения/записи данных файлов приложения
  • jsonScanner: лексический анализатор исходников json
Light bulb  Примечание: В fpjson, доступ, например, SomeJSONObject.Integers['цена'] может дать Нарушение SIGSEGV/Access, если это целая переменная не существует. Это, очевидно, сделано намеренно, см [[1]].

Вы должны были бы использовать метод Find (доступен в FPC 2.6.2), чтобы сначала проверить, существует ли элемент ('цена' в данном примере).

Маршаллинг

fcl-json содержит юнит "fpjsonrtti", который используется для загрузки из объектов или сохранения их в формате JSON(экземпляров TObject).

Смотрите Streaming JSON для короткого примера.

Примеры

Итак ,начнём

USES fpjson, jsonparser;

PROCEDURE JSONTest;
VAR
   jData : TJSONData;
   jObject : TJSONObject;
   jArray : TJSONArray;
   s : string;
BEGIN   
   // это лишь минимальный пример того, что можно сделать с помощью этого API

   // создать строки JSON
   jData := GetJSON('{"поле1" : "Привет", "поле2" : 42, "Цвет" : ["Красный", "Зелёный", "Голубой"]}');

   // вывести как плоскую строку
   s := jData.AsJSON;

   //  вывести замечательно-отформатированный JSON
   s := jData.FormatJSON;

   // передан как TJSONObject для простого доступа
   jObject := TJSONObject(jData);

   // передача значения ключа "поле1"
   s := jObject.Get('поле1');

   // передача значения ключа "поле2"
   jObject.Integers['Fld2'] := 123;

   // передача второго цвета
   s := jData.FindPath('Цвет[1]').AsString;

   // add a new element
   jObject.Add('Happy', True);

   // передать новый подмассив
   jArray := TJSONArray.Create;
   jArray.Add('Север');
   jArray.Add('Юг');
   jArray.Add('Восток');
   jArray.Add('Запад');
   jObject.Add('Направление', jArray);

END;

Сохранение/загрузка позиции/размера диалога

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;

Сохранение/загрузка TStringList

//Пример пути: '/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;

Bp JsonViewer

Пример использования можно найти в инструментах Lazarus: jsonviewer (расположенный в lazarus/tools/jsonviewer). В частности, эта часть инструмента показывает, как использовать 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

The fpctwit library makes use of JSON to send/receive data.

See also