Delphi 10.3从JSONObject更新Sub-TObject

时间:2019-02-14 13:54:51

标签: json parsing delphi delphi-10.3-rio subobject

我有一个像这样的JSON文件:

{"Gradient":[{
  "Points":[{}],
  "Style":"Linear",
  "StartPosition":[{"X":"0","Y":"0"}],
  "StopPosition":[{"X":"0","Y":"1"}]
  }]
}

,我想创建一个自动解析过程来从此JSON更新对象及其子对象。 (我已经尝试过编组和取消编组,但是它不起作用,因为我混合了我自己的对象和未编组的系统对象)。

所以我使用RTTI编写了这段代码,但是当我想在此过程中更新子对象时遇到问题:

uses
  REST.JSON, System.Generics.Collections, system.JSON, RTTI, TypInfo, System.Types;

...

class procedure TJSONUtils.FromJSON(aSender: TObject ; aJSONO : TJSONObject);
const
  SKIP_PROP_TYPES = [tkUnknown, tkInterface];
var
  vC : TRttiContext;
  vType : TRttiType;
  vProperty : TRttiProperty;
  vValue : TValue;
  vPropName : string;
  vJSONPair : TJSONPair;

begin
  // Get RTTI of aSender Object
  vC := TRttiContext.Create;
  vType := vC.GetType(aSender.ClassInfo);

  for vJSONPair in aJSONO do
  begin
    if vJSONPair.JsonValue is TJSONArray then
    begin
      // JSON contain object or Record data
      for vProperty in vType.GetProperties do
      begin
        if (vProperty.IsReadable) and not (vProperty.PropertyType.TypeKind in SKIP_PROP_TYPES) and (vProperty.Visibility = mvPublished ) then
        begin
          if vProperty.Name = vPropName then
          begin
            vValue := vProperty.GetValue(aSender);
            if vValue.IsObject then
            begin
              // IS OBJECT
              TJSONUtils.FromJSON((vProperty.GetValue(aSender) as vProperty.ClassType), vJSONPair);   // error here
            end
            else // if vValue.IsArray then
            begin
              // IS ARRAY or record ?
              TJSONUtils.FromJSON((vProperty.GetValue(aSender) as vProperty.ClassType), vJSONPair);   // error here
            end;
          end;
        end;
      end;
    end
    else
    begin
      // low level data (string, integer, real, etc...)
      vPropName := StringReplace(vJSONPair.JsonString.Value, '"', '', [rfReplaceAll]);
      for vProperty in vType.GetProperties do
      begin
        if (vProperty.IsReadable) and not (vProperty.PropertyType.TypeKind in SKIP_PROP_TYPES) and (vProperty.Visibility = mvPublished ) then
        begin
          if vProperty.Name = vPropName then
          begin
            vProperty.SetValue(aSender, stringReplace(stringReplace(vJSONPair.JsonValue.ToString, '"', '', [RfReplaceAll]), '''', '', [RfReplaceAll]));
          end;
        end;
      end;
    end;
  end;
end;

我递归调用该过程时出错。我想在参数中传递子对象,但是我写它的方式不起作用。您知道如何使它正常工作吗? (用于子对象,子数组或记录)。

注意:它必须是动态的,因为我永远都不知道对象的结构是什么。

0 个答案:

没有答案