Sign in Join
Wiki copytemporary

Revision 3 of 3, by WikiArchive on 11-9-2026. The page as it is now.

fcl-json/ru

Информация

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

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

https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png Примечание: В fpjson, доступ, например, SomeJSONObject.Integers['цена'] может дать Нарушение SIGSEGV/Access, если это целая переменная не существует. Это, очевидно, сделано намеренно, см [1(http://bugs.freepascal.org/view.php?id=22273)].

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

Маршаллинг

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

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

Примеры

Итак, начнём

pascal
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['поле2'] := 123;
    
       // передача второго цвета
       s := jData.FindPath('Цвет[1]').AsString;
    
       // добавить новый элемент
       jObject.Add('Happy', True);
    
       // передать новый подмассив
       jArray := TJSONArray.Create;
       jArray.Add('Север');
       jArray.Add('Юг');
       jArray.Add('Восток');
       jArray.Add('Запад');
       jObject.Add('Направление', jArray);
    
    END;

Перемещение пунктов

pascal
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;

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

pascal
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

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

Использование JsonViewer

Пример использования можно найти в инструментах Lazarus: jsonviewer (расположенный в lazarus/tools/jsonviewer). В частности, эта часть инструмента показывает, как использовать JSON:

pascal
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;

Библиотека Components and Code examples использует JSON для передачи/приема данных.

Изменение формата чисел с плавающей запятой

Вопрос: моя программа генерирует и записывает данные в файл JSON. Я использую метод FormatJSON(), чтобы сделать вывод более читабельным. Меня не совсем устраивает, как выглядят числа с плавающей точкой:

pascal
"coordinates" : [
         5.5978631048365003E+001,
         2.2100000000000000E+002
    ]

Я хочу видеть нормальную форму:

pascal
"coordinates" : [
         55.978631048365003,
         221.0
    ]

Ответ: (пользователи форума y.ivanov , rvk , wp):

pascal
{$mode objfpc}{$h+}
    uses
      fpjson,
      jsonparser,
      SysUtils;
     
    type
      TJSONFloat4Number = class(TJSONFloatNumber)
      protected
        function GetAsString: TJSONStringType; override;
      end;
     
    function TJSONFloat4Number.GetAsString: TJSONStringType;
    var
      F: TJSONFloat;
      fs: TFormatSettings;
    begin
      fs := DefaultFormatSettings;
      fs.DecimalSeparator := '.';
      F := GetAsFloat;
      Result := FormatFloat('0.0###############', F, fs); // форматирование с вашими предпочтениями
    end;
    
    procedure JSONTest;
    var
      jData: TJSONData;
    begin
      jData := GetJSON('{"coordinates": [5.5978631048365003E+001, 2.2100000000000000E+002]}');
      writeln(jData.FormatJSON);
      jData.Free;
    end;
     
    begin
      SetJSONInstanceType(jitNumberFloat, TJSONFloat4Number);
      JSONTest;
      Readln;
    end.

Смотрите также


From the Free Pascal wiki, page "fcl-json/ru", as the Internet Archive kept it on 2025-08-31, last changed on 2025-02-25. 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.