【源码】号称DELPHI最快的JSON库 JsonDataObjects 支持跨平台 支持XE11下载及示例

  • 特征

    快速双重JSON解析器,无需转换即可解析UTF8和UTF16

    自动创建数组和对象

    带有隐式运算符的轻松访问模式

    紧凑和格式化的输出模式

    变体支持

    如果JsonSerializationConfig.NullConvertsToValueTypes设置为True,则可以将Null自动转换为值类型。

    进度回调支持,用于加载大型JSON字符串

    Win32,Win64和ARM Android支持(MacOS和iOS可以工作)


  • JsonDataObjects基本演示

图片[1]-【源码】号称DELPHI最快的JSON库 JsonDataObjects 支持跨平台 支持XE11下载及示例-Delphi编程技巧大全

Json数据

{
  "name": "张三",
  "age": 33,
  "sex": true,
  "weight": 123.456,
  "tel": ["86-1111111", "86-2222222"],
  "addresses":{"address":"A省B市",
"pc":"100001"},
  "children": [
    {
      "name": "张继",
      "age": "22",
      "sex": true
    },
    {
      "name": "张承",
      "age": "11",
      "sex": false
    }
  ]
}

窗体上放上两个Memo控件,左边存放Json,另一个输出Json值

uses JsonDataObjects;
 
procedure TForm1.Button1Click(Sender: TObject);
var
    jo: TJsonObject;
    i: Integer;
begin
    jo := TJsonObject.Parse( Memo1.Text) as TJsonObject;
 
    Memo2.Lines.Add(jo['name']);
    Memo2.Lines.Add(jo['age']);
    Memo2.Lines.Add(jo['sex']);
    Memo2.Lines.Add(jo['weight']);
    Memo2.Lines.Add(jo['tel'].Items[]);
    Memo2.Lines.Add(jo['tel'].Items[]);
    Memo2.Lines.Add(jo['addresses'].S['address']);
    Memo2.Lines.Add(jo['addresses'].S['pc']);
    Memo2.Lines.Add('总共数据数:' + inttostr(jo['children'].Count));
    for i :=  to jo['children'].Count -  do
    begin
        Memo2.Lines.Add(jo['children'].Items[i]['name']);
        Memo2.Lines.Add(jo['children'].Items[i]['age']);
        Memo2.Lines.Add(jo['children'].Items[i]['sex']);
    end;
    jo.Free;
end;

  • JsonDataObjects序列和还原

// Use delphi 10.2.1

unit ujson;

interface

uses
  System.SysUtils, soap.EncdDecd, Web.HTTPApp, System.NetEncoding, Data.DB,
  System.Classes, JsonDataObjects;

// {"data":[{"field1":value1,"field2":value2}]};
function datasetToJson(dataset: TDataSet): string;

// {"data":[{"field1":value1,"field2":value2}]};
procedure jsonToDataset(const json: string; dataset: TDataSet);

// {"cols":[{"name":"field1","size":0,"type":"int"}]"data":[{"field1":value1}]};
function datasetToJsonCols(dataset: TDataSet): string;

// {
// "update":[{"table":"表1","where":"字段1=1","字段1":"1","字段2":0}]
// ,"insert":[{"table":"表1","字段1":"1","字段2":0}]
// ,"delete":[{"table":"表1","where":"字段1=1"}]
// };
procedure parseJsonSql(const json: string; outsql: TStrings);

implementation

procedure parseJsonSql(const json: string; outsql: TStrings);
// {
// "update":[{"table":"表1","where":"字段1=1","字段1":"1","字段2":0}]
// ,"insert":[{"table":"表1","字段1":"1","字段2":0}]
// ,"delete":[{"table":"表1","where":"字段1=1"}]
// };
var
  obj, childobj: TJsonObject;
  tablename, sql, lname, lvalue, where: string;
  i, j: Integer;

  function _getValue(value: PJsonDataValue): string;
{
TJsonDataType = (
jdtNone, jdtString, jdtInt, jdtLong, jdtULong, jdtFloat, jdtDateTime
, jdtBool, jdtArray, jdtObject
);
}
  begin
    case value.Typ of
      jdtString:
        Result := QuotedStr(UTF8ToString(rawbytestring(TNetEncoding.URL.Decode(value.Value)))); // 解码
      jdtBool:
        Result := BoolToStr(value.BoolValue);
      jdtFloat:
        Result := FloatToStr(value.FloatValue);
      jdtInt, jdtLong, jdtULong:
        Result := IntToStr(value.IntValue);
      jdtDateTime:
        Result := DateTimeToStr(value.DateTimeValue);
    end;
  end;

begin
  if outsql = nil then
    Exit;
  outsql.Clear;
  obj := TJsonObject.Parse(json) as TJsonObject;
  try
// 解析并生成insert sql begin-----------------------------------
    for i := 0 to obj.A['insert'].Count - 1 do
    begin
      childobj := obj.A['insert'].O[i];
      lname := '';
      lvalue := '';
      for j := 0 to childobj.Count - 1 do
      begin
        if childobj.Names[j] = 'table' then
        begin
          tablename := childobj.Items[j].value;
          Continue;
        end;
        if lname = '' then
          lname := childobj.Names[j]
        else
          lname := lname + ',' + childobj.Names[j];
        if lvalue = '' then
          lvalue := _getValue(childobj.Items[j])
        else
          lvalue := lvalue + ',' + _getValue(childobj.Items[j]);
      end;
      sql := 'insert into ' + tablename + ' (' + lname + ') values (' + lvalue + ')';
      outsql.Add(sql);
    end;
// 解析并生成insert sql end----------------------------------------
// 解析并生成update sql begin---------------------------------------
    for i := 0 to obj.A['update'].Count - 1 do
    begin
      childobj := obj.A['update'].O[i];
      lname := '';
      lvalue := '';
      for j := 0 to childobj.Count - 1 do
      begin
        if childobj.Names[j] = 'table' then
        begin
          tablename := childobj.Items[j].value;
          Continue;
        end
        else if childobj.Names[j] = 'where' then
        begin
          where := childobj.Items[j].value;
          Continue;
        end;
        if lname = '' then
          lname := childobj.Names[j] + '=' + _getValue(childobj.Items[j])
        else
          lname := lname + ',' + childobj.Names[j] + '=' + _getValue(childobj.Items[j]);
      end;
      sql := 'update ' + tablename + ' set ' + lname + ' where ' + where;
      outsql.Add(sql);
    end;
// 解析并生成update sql end--------------------------------------------
// 解析并生成delete sql begin--------------------------------------------
    for i := 0 to obj.A['delete'].Count - 1 do
    begin
      childobj := obj.A['delete'].O[i];
      lname := '';
      lvalue := '';
      for j := 0 to childobj.Count - 1 do
      begin
        if childobj.Names[j] = 'table' then
        begin
          tablename := childobj.Items[j].value;
          Continue;
        end
        else if childobj.Names[j] = 'where' then
        begin
          where := childobj.Items[j].value;
          Continue;
        end;
      end;
      sql := 'delete from ' + tablename + ' where ' + where;
      outsql.Add(sql);
    end;
// 解析并生成delete sql end-------------------------------------------
  finally
    obj.free;
  end;
end;

function datasetToJsonCols(dataset: TDataSet): string;
// {"cols":[{"name":"field1","size":0,"type":"int"}]"data":[{"field1":value1}]};
var
  i: Integer;
  obj, childobj: TJsonObject;
  field: TField;
  blob: TStringStream;

  function _getFieldType(fld: TField): string;
  begin
    case fld.DataType of
      ftBoolean:
        Result := 'bool';
      ftSmallint, ftInteger, ftWord, ftAutoInc:
        Result := 'int';
      ftLargeint:
        Result := 'int64';
      ftFloat, ftBCD, ftCurrency:
        Result := 'float';
      ftTimeStamp, ftDate, ftTime, ftDateTime:
        Result := 'datetime';
      ftString, ftFixedChar, ftMemo, ftWideString:
        Result := 'string';
      ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
        Result := 'blob';
    end;
  end;

begin
// {"cols":[{"name":"c1","size":0,"type":"int"}]"data":[{"c1":1}]};
  Result := '{"result":"false"}';
  if (dataset = nil) or (not dataset.Active) then
    Exit;
  obj := TJsonObject.Create;
  obj.A['cols'];
  obj.A['data'];
  dataset.First;
  for i := 0 to dataset.FieldCount - 1 do // fill cols array
  begin
    field := dataset.Fields[i];
    childobj := obj.A['cols'].AddObject;
    childobj.S['name'] := field.FieldName;
    childobj.I['size'] := field.Size;
    childobj.S['type'] := _getFieldType(field);
    childobj.B['required'] := field.Required;
    childobj.B['readonly'] := field.ReadOnly;
  end;
// fill data array
  dataset.First;
  while not dataset.Eof do
  begin
    childobj := obj.A['data'].AddObject;
    for i := 0 to dataset.FieldCount - 1 do
    begin
      field := dataset.Fields[i];
      if field.IsNull then
        childobj.S[field.FieldName] := ''
      else
      begin
        case field.DataType of
          ftBoolean:
            childobj.B[field.FieldName] := field.AsBoolean;
          ftSmallint, ftInteger, ftWord, ftAutoInc:
            childobj.I[field.FieldName] := field.AsInteger;
          ftLargeint:
            childobj.L[field.FieldName] := TLargeintField(field).AsLargeInt;
          ftFloat, ftBCD, ftCurrency:
            childobj.F[field.FieldName] := field.AsFloat;
          ftTimeStamp, ftDate, ftTime, ftDateTime:
            childobj.D[field.FieldName] := field.AsDateTime;
          ftString, ftFixedChar, ftMemo, ftWideString:
            childobj.S[field.FieldName] := TNetEncoding.URL.Encode(string(UTF8Encode(field.AsString))); // 编码
          ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
            begin
              blob := TStringStream.Create('');
              try
                TBlobField(field).SaveToStream(blob);
                childobj.S[field.FieldName] := EncodeString(blob.DataString); // base64 编码
              finally
                blob.Free;
              end;
            end;
        end;
      end;
    end; // end for
    dataset.Next;
  end; // end while
  Result := obj.ToString;
end;

procedure jsonToDataset(const json: string; dataset: TDataSet);
// {"data":[{"field1":value1,"field2":value2}]};
var
  obj, childobj: TJsonObject;
  i, j: Integer;
  field: TField;
  blob: TStringStream;
begin
  if (dataset = nil) or (not dataset.Active) or (json = '{"result":"false"}') then
    Exit;
  obj := TJsonObject.Parse(json) as TJsonObject;
  dataset.DisableControls;
  try
    for i := 0 to obj.A['data'].Count - 1 do
    begin
      dataset.Append;
      childobj := obj.A['data'].O[i];
      if childobj = nil then
        continue;
      for j := 0 to dataset.FieldCount - 1 do
      begin
        field := dataset.Fields[j];
        if field = nil then
          Continue;
        case field.datatype of
          ftBoolean:
            field.AsBoolean := childobj.B[field.FieldName];
          ftFloat, ftBCD, ftCurrency:
            field.AsFloat := childobj.F[field.FieldName];
          ftSmallint, ftInteger, ftWord, ftAutoInc:
            field.AsInteger := childobj.I[field.FieldName];
          ftString, ftFixedChar, ftMemo, ftWideString:
            field.AsString := UTF8ToString(rawbytestring(TNetEncoding.URL.Decode(childobj.S[field.FieldName]))); // 解码
          ftTimeStamp, ftDate, ftTime, ftDateTime:
            field.AsDateTime := childobj.D[field.FieldName];
          ftLargeint:
            TLargeintField(field).AsLargeInt := childobj.L[field.FieldName];
          ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
            begin
              blob := TStringStream.Create(DecodeString(childobj.S[field.FieldName]));
              try
                TBlobField(field).LoadFromStream(blob);
              finally
                blob.Free;
              end;
            end;
        end;
      end;
      dataset.Post;
    end;
  finally
    dataset.EnableControls;
    obj.free;
  end;
end;

function datasetToJson(dataset: TDataSet): string;
// {"data":[{"field1":value1,"field2":value2}]};
var
  i: Integer;
  obj, childobj: TJsonObject;
  field: TField;
  blob: TStringStream;
begin
  Result := '{"result":"false"}';
  if (dataset = nil) or (not dataset.Active) then
    Exit;
  obj := TJsonObject.Create;
  try
    obj.A['data'];
    dataset.First;
    while not dataset.Eof do
    begin
      childobj := obj.A['data'].AddObject;
      for i := 0 to dataset.FieldCount - 1 do
      begin
        field := dataset.Fields[i];
        if field.IsNull then
          childobj.S[field.FieldName] := ''
        else
        begin
          case field.datatype of
            ftBoolean:
              childobj.B[field.FieldName] := field.AsBoolean;
            ftSmallint, ftInteger, ftWord, ftAutoInc:
              childobj.I[field.FieldName] := field.AsInteger;
            ftLargeint:
              childobj.L[field.FieldName] := TLargeintField(field).AsLargeInt;
            ftCurrency, ftFloat, ftBCD:
              childobj.F[field.FieldName] := field.AsFloat;
            ftTimeStamp, ftDate, ftTime, ftDateTime:
              childobj.D[field.FieldName] := field.AsDateTime;
            ftString, ftFixedChar, ftMemo, ftWideString:
              childobj.S[field.FieldName] := TNetEncoding.URL.Encode(string(UTF8Encode(field.AsString)));
            ftBytes, ftVarBytes, ftBlob, ftGraphic, ftOraBlob, ftOraClob:
              begin
                blob := TStringStream.Create('');
                try
                  TBlobField(field).SaveToStream(blob);
                  childobj.S[field.FieldName] := EncodeString(blob.DataString); // base64 编码
                finally
                  blob.Free;
                end;
              end;
          end;
        end;
      end; // end for
      dataset.Next;
    end; // end while
    Result := obj.ToString;
  finally
    obj.Free;
  end;
end;

end.

 

  • 又一个示例:

var

  Obj: TJsonObject;

begin

  Obj := TJsonObject.Parse('{ "foo": "bar", "array": [ 10, 20 ] }') as TJsonObject;

  try

    ShowMessage(Obj['foo']);

    ShowMessage(IntToStr(Obj['array'].Count));

    ShowMessage(IntToStr(Obj['array'].Items[0]));

    ShowMessage(IntToStr(Obj['array'].Items[1]));

  finally

    Obj.Free;

  end;

end;

Filling and serializing JSON objects



var

  Obj, ChildObj: TJsonObject;

begin

  Obj := TJsonObject.Create;

  try

    // easy access

    Obj['foo'] := 'bar';

    // normal (and faster) access

    Obj.S['bar'] := 'foo';

    // automatic array creation, Obj is the owner of 'array'

    Obj.A['array'].Add(10);

    Obj.A['array'].Add(20);

    // automatic object creation, 'array' is the owner of ChildObj

    ChildObj := Obj.A['array'].AddObject;

    ChildObj['value'] := 12.3;

    // automatic array creation, ChildObj is the owner of 'subarray'

    ChildObj.A['subarray'].Add(100);

    ChildObj.A['subarray'].Add(200);



    ShowMessage(Obj.ToJSON({Compact:=}False));

  finally

    Obj.Free;

  end;

{

"foo": "bar",

"bar": "foo",

"array": [

10,

20,

{

"value": 12.3,

"subarray": [

100,

200

]

}

]

}

Copying JSON objects with Assign



var

  Obj, ClonedObj: TJsonObject;

begin

  Obj := TJsonObject.ParseUtf8('{ "foo": [ "bar", {}, null, true, false, { "key": "value" } ] }') as TJsonObject;

  try

    ClonedObj := TJsonObject.Create;

    try

      // Make a copy of Obj

      ClonedObj.Assign(Obj);

      ShowMessage(ClonedObj.ToJSON(False));

    finally

      ClonedObj.Free;

    end;

  finally

    Obj.Free;

  end;

end;

{

"foo": [

"bar",

{},

null,

true,

false,

{

"key": "value"

}

]

}

https://github.com/ahausladen/JsonDataObjects

THE END
文章版权归作者所有,未经允许请勿转载。
点赞5赞赏
评论 共5条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片