DataSet Json 转化

来自 蓝颜2756215016

function DataSetToJson(ADataSet: TClientDataSet; All: Boolean): ISuperObject;
var
  i: Integer;
  json: ISuperObject;
  f: TField;
  ws: WideString;
begin
  if ADataSet.State in [dsEdit,dsInsert] then ADataSet.Post;
  if All then
  begin
    Result := TSuperObject.Create(stArray);
    ADataSet.First;
    while not ADataSet.Eof do
    begin
      json := TSuperObject.Create(stObject);
      for i := 0 to ADataSet.FieldCount -1 do
      begin
        f := ADataSet.Fields[i];
        if f.FieldKind <> fkData then Continue;
        if not f.IsNull then
        begin
          case f.DataType of
            ftString:
              begin
                ws := f.AsString;
                json.S[LowerCase(f.FieldName)] := ws;
              end;

            ftBoolean:
              json.B[LowerCase(f.FieldName)] := f.AsBoolean;
            ftInteger:
              json.I[LowerCase(f.FieldName)] := f.AsInteger;
            ftFloat:
              json.D[LowerCase(f.FieldName)] := f.AsFloat;
            ftDate,ftDateTime:
              json.I[LowerCase(f.FieldName)] := DelphiToJavaDateTime(f.AsDateTime);
          else
             begin
                ws := f.AsString;
                json.S[LowerCase(f.FieldName)] := ws;
              end;
          end;
        end;
      end;
      Result.AsArray.Add(json);
      ADataSet.Next;
    end;
  end   
  else begin
    json := TSuperObject.Create(stObject);
    for i := 0 to ADataSet.FieldCount -1 do
    begin
      f := ADataSet.Fields[i];
      if not f.IsNull then
      begin
        case f.DataType of
          ftString:
            begin
              ws := f.AsString;
              json.S[LowerCase(f.FieldName)] := ws;
            end;
          ftBoolean:
            json.B[LowerCase(f.FieldName)] := f.AsBoolean;
          ftInteger:
            json.I[LowerCase(f.FieldName)] := f.AsInteger;
          ftFloat:
            json.D[LowerCase(f.FieldName)] := f.AsFloat;
          ftDate,ftDateTime:
            json.I[LowerCase(f.FieldName)] := DelphiToJavaDateTime(f.AsDateTime);
        else
          begin
            ws := f.AsString;
            json.S[LowerCase(f.FieldName)] := ws;
          end;
        end;
      end;
    end;
    Result := json;
  end;
end;
procedure JsonToDataSet(AJson: ISuperObject;ADataSet: TClientDataSet);
  procedure setFieldValue(f:TField;val: ISuperObject);
  var
    vReadOnly: Boolean;
    OldEvent: TFieldNotifyEvent;
  begin
    vReadOnly := f.ReadOnly;
    f.ReadOnly := false;
    OldEvent := f.OnChange;
    f.OnChange := nil;
    try
      case f.DataType of
        ftString: f.AsString := val.AsString;
        ftInteger: f.AsInteger := val.AsInteger;
        ftBoolean: f.AsBoolean := val.AsBoolean;
        ftFloat: f.AsFloat := val.AsDouble;
        ftDate,ftDateTime: f.AsDateTime := JavaToDelphiDateTime(val.AsInteger);
        else
          f.AsString := val.AsString;
      end;
    finally
      f.ReadOnly := vReadOnly;
      f.OnChange := OldEvent;
    end;
  end;
var
  item: TSuperObjectIter;
  json: ISuperObject;
  jsonArr: TSuperArray;
  i: integer;
  AChildDataSet: TLDataSet;
  vReadOnly: Boolean;
begin
  vReadOnly := ADataSet.ReadOnly;
  ADataSet.ReadOnly := False;
  item.Ite := nil;
  try
    if AJson.DataType = stArray then
    begin
      jsonArr := AJson.AsArray;
      ADataSet.DisableControls;
      for i := 0 to jsonArr.Length -1 do
      begin
        json := jsonArr.O[i];      
        ADataSet.Append;
        if ObjectFindFirst(json, item) then
        repeat
          if (ADataSet.FindField(item.key) <> nil) and
           (item.val.DataType <> stNull) then
            setFieldValue(ADataSet.FieldByName(item.key),item.val);
        until not ObjectFindNext(item);
        ADataSet.Post;
      end;
      ADataSet.EnableControls;
    end
    else begin
      json := AJson;
      ADataSet.Append;
      if ObjectFindFirst(json, item) then
      repeat
        if (ADataSet.FindField(item.key) <> nil) and
         (item.val.DataType <> stNull) then
        begin
          setFieldValue(ADataSet.FieldByName(item.key),item.val);
        end;         

      until not ObjectFindNext(item);
      ADataSet.Post;
    end;
  finally
    ADataSet.ReadOnly := vReadOnly;
    if item.Ite <> nil then
      ObjectFindClose(item);
  end;
end;
原文地址:https://www.cnblogs.com/jialiguo/p/3478097.html