在Datasnap中旋转数据集JSON结果(Delphi 10)

时间:2016-04-20 10:38:33

标签: json delphi datasnap delphi-10-seattle

我正在尝试轮换使用Datasnap返回的数据集的结果。

示例:这就是我得到的

{"result":[{"table":[["REG_KEY",1,0,0,2,3,0,0,false,false,0,false,false],["REG_NAME",1,1,0,128,129,0,0,false,false,0,false,false]],"REG_KEY":["01","02"],"REG_NAME":["BALEARES","CANARIAS"]}]}

我想将其转换为:

[{"REG_KEY":"01","REG_NAME":"BALEARES"},{"REG_KEY":"02","REG_NAME":"CANARIAS"}]

我打算在DSHTTPWebDispatcher.FormatResult中对其进行转换,但这是我第一次使用DataSnap / REST / JSON,我在理解管理JSON值的类时遇到了问题。

它应该是这样的:

procedure TWebModule1.DSHTTPWebDispatcher1FormatResult(Sender: TObject; var ResultVal: TJSONValue; const Command: TDBXCommand; var Handled: Boolean);
var
    Aux: TJSONObject;
    NewResult: TJSONObject;
    Row: TJSONObject;
    NumField, NumRow, MaxFields, MaxRows: integer;
begin
    Handled := True;
    NewResult := TJSONArray.Create;
    Aux := TJSONArray(ResultVal).Get(0);  // I get the result as an Object instead of an Array
    MaxFields := Aux.Pairs.Count - 1; // I ignore the Pair 0 because it only contains the Dataset structure
    MaxRows := TJSONArray(1).Count;
    for NumRow := 0 to MaxRows - 1 do begin
        Row := TJSONObject.Create;
        for NumField := 1 to MaxFields do begin
            Row.AddPair(Aux.Pairs[NumField].JsonString, 
                        TJSONArray(Aux.Pairs[NumField].JsonValue).Get(NumRow));
        end;
        Aux.Add(Row);
    end;
    Aux.Free;
    ResultVal.Free;
    ResultVal := NewResult;
end;

但是TJSONObject没有Pairs.Count方法来知道有多少对包含,而TJSONArray没有和Add方法直接添加新对象。我很确定这段代码还有很多其他错误。

有人可以指导我如何修复它吗?

2 个答案:

答案 0 :(得分:2)

我明白了: - )

此代码执行我查找的转换(它执行循环遍历行和列的双循环,并将结果旋转为新的JSON):

procedure TWebModule1.DSHTTPWebDispatcher1FormatResult(Sender: TObject; var ResultVal: TJSONValue; const Command: TDBXCommand; var Handled: Boolean);
var Aux: TJSONObject;
    NewResult: TJSONValue;
    Row: TJSONObject;
    NumField, NumRow, MaxFields, MaxRows: integer;
begin  
  Handled := True;

  if ResultVal.ToJSON = '[{"table":[]}]' then begin
    TJSONArray(ResultVal).Remove(0);
  end
  else if (LowerCase(Copy(ResultVal.ToJSON, 1, 10)) = '[{"table":') then begin // For Datasets I rotate its content so it comes as rows and not as columns
    NewResult := TJSONArray.Create;
    Aux := TJSONObject(TJSONArray(ResultVal).Get(0));

    MaxFields := Aux.Count - 1;  // I ignore the Pair 0 because it only contains the Dataset structure
    MaxRows := TJSONArray(TJSONPair(Aux.Get(1)).JSONValue).Count;

    for NumRows := 0 to MaxRows - 1 do begin
      Row := TJSONObject.Create;
      for NumFields := 1 to MaxFields do begin
        Row.AddPair(Aux.Pairs[NumField].JsonString.Value,
                     TJSONArray(Aux.Pairs[NumField].JsonValue).Get(NumRow).Clone as TJSONValue);
      end;
      TJSONArray(NewResult).AddElement(Row);
    end;

    ResultVal.Free;              // I free the old Result because a new one is returned (Aux is already supposed to be freed when freeing ResultVal)
    ResultVal := NewResult;       
  end;
end;

答案 1 :(得分:2)

将此内容放入网络模块

procedure TWebModule1.DSHTTPWebDispatcher1FormatResult(Sender: TObject;
 var ResultVal: TJSONValue; const Command: TDBXCommand;
              var Handled: Boolean);
var
  Aux: TJSONValue;
begin
    Aux := ResultVal;
    ResultVal := TJSONArray(Aux).Get(0);
    TJSONArray(Aux).Remove(0);
    Aux.Free;
end;

你的结果将是这个

{"result":[{...},{...}]}