Sign in Join
Wiki copytemporary

fcl-json/ru

English · Polski · Русский · 中文(中国)

Информация

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.

Revision 3, last changed by WikiArchive .

Edited on wiki.freepascal.org by 5 people, 2016–2022

From the official wiki's backup of 26 May 2024: who edited this page there, and when. Edits made there after that date were not recorded, and the earlier versions are not shown here; the main page says why.

WhenWhoWhat changed
Prospero78suCreated page
Prospero78su
Prospero78su
Prospero78suИнформация
Prospero78suИнформация
Prospero78suИнформация
Prospero78suИнформация
Prospero78suИнформация
Prospero78suИнформация
Prospero78suИнформация
Prospero78suИнформация
Prospero78su
Prospero78suИнформация
Prospero78suStreaming
Prospero78suМаршаллинг
FTurtle
Prospero78suExamples
Prospero78suGetting Started
Prospero78suИтак ,начнём
Prospero78suИтак ,начнём
Prospero78suSave/load dialog position/size
Prospero78suSave/load TStringList
Prospero78suСохранение/загрузка TStringList
Prospero78suFrom JsonViewer
Prospero78suFpcTwit
Prospero78suSee also
Prospero78suИтак ,начнём
Prospero78suИтак ,начнём
Prospero78suИтак ,начнём
Prospero78suBp JsonViewer
Prospero78suИтак ,начнём
ZoltanleoИтак, начнём
ZoltanleoСохранение/загрузка позиции/размера диалога
ZoltanleoСохранение/загрузка TStringList
ZoltanleoИспользование JsonViewer
DbannonFpcTwit
Dbannonupdated address for fpctwit
DbannonFpcTwit
ZoltanleoСохранение/загрузка позиции/размера диалога
ZoltanleoTraversing Items
AlextpFpcTwit: why a header here?
ZoltanleoИспользование JsonViewer
ZoltanleoChange formatting of float numbers

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.