SuperObject多维数组

时间:2013-06-01 21:22:05

标签: json delphi multidimensional-array superobject

我正在使用Delphi XE4和SuperObject 1.24

我有以下结构:

type
  TMyArray = Array of Array of Variant;
  TMyRecord = Record
     Values : TMyArray;
  end;

var
 T,W : TMyRecord;
 S : String;
 i : integer;

begin
 SetLength(T.Values, 2 );
 for i := 0 to 1 do
   SetLEngth(T.Values[i],2);

 T.Values[0,0] := 'Hello World';
 T.Values[0,1] := 'Foo';
 T.Values[1,0] := 'Bar';
 T.Values[1,1] := 'is here';

 R := TSuperRttiContext.Create;

 S := R.AsJson<TMyRecord>(T).AsString;
 W := R.AsType<TMyRecord>( SO(S) );
 R.Free;
end;

S包含似乎正确的{"Values":[["Hello World","Foo"],["Bar","is here"]]}

W显示(((Delphi exception EVariantBadVarTypeError at $294AD325, Variant array of Unknown), (Variant array of Unknown, Variant array of Unknown)))

如何正确重新创建多维数组?

1 个答案:

答案 0 :(得分:3)

我找到了实现它的方法。我在谷歌搜索了很多,但我找不到任何我可以使用的东西:( 这是我写的代码:

// Types and routines
type
  TMyArray = Array of Array of Variant;
  TMyRecord = Record
     Lines   : Integer;
     Columns : Integer;
     Values  : TMyArray;
  end;

 function JSONToDynVariantArray( ctx: TSuperRttiContext; const aObj : ISuperObject;
      var aValue : TValue ) : Boolean;
 var
   i,j: Integer;
  Row,
  Col : ISuperObject;
  SuperType : TSuperType;

  MyData : TMyRecord;

begin
  SuperType := ObjectGetType(aObj);
  case SuperType of
     stNull : begin
       aValue := nil;
       Result := True;
     end;
     stArray : Begin
     End;
    stObject : Begin
        MyData.Lines := aObj.I['Lines'];
        MyData.Columns   := aObj.I['Columns'];
        SetLength(RecData.Values, MyData.Lines, MyData.Columns );
        for i := 0 to aObj.A['Values'].Length -1 do begin
           Row :=  aObj.A['Values'][i];
            for j := 0 to Row.AsArray.Length -1 do begin
                Col := Row.AsArray[j];
                SuperType := ObjectGetType(Col);
                case SuperType of
                   stNull     : MyData.Values[i,j] := varNull;
                   stBoolean  : MyData.Values[i,j] := Col.AsBoolean;
                   stDouble   : MyData.Values[i,j] := Col.AsDouble;
                   stCurrency : MyData.Values[i,j] := Col.AsCurrency;
                   stInt      : MyData.Values[i,j] := Col.AsInteger;
                   stString   : MyData.Values[i,j] := Col.AsString;
                end;
            end;
        end;
        TValue.Make(@MyData, Typeinfo(TMyRecord), aValue);
        Result := True;
    End;
  end;
end;

// Main code

var
  T ,
  W : TMyRecord;
  S : String;
  R : TSuperRttiContext;

begin
  inherited;
  T.Lines := 2;
  T.Columns   := 2;
  SetLength(T.Values, T.Lines,T.Columns );
  T.Values[0,0] := 'Hello World';
  T.Values[0,1] := Date;
  T.Values[1,0] := 10;
  T.Values[1,1] := 234.45;

  R := TSuperRttiContext.Create;

  // This is a very nice feature!!!
  R.SerialFromJson.Add(TypeInfo(TMyRecord), JSONToDynVariantArray );

  S := R.AsJson<TMyRecord>(T).AsString;
  W := R.AsType<TMyRecord>( SO(S) );

  R.Free;
end;

HTH, Clément