使用Delphi Xe5将JSON转换为StringList

时间:2013-11-08 00:20:58

标签: json delphi delphi-xe5

我正在使用Delphi Xe5,我有一个基本上使用IDTCPCLient(套接字)与服务器通信的组件,并以JSON的形式检索数据。我已经免除了你所有的连接代码等。它的工作原理。返回的JSon也可以。我遇到的麻烦是将我的JSON转换为StringList,然后我将其用于向列表框写出值列表,并将其余的JSON数据对象存储在TSTrings OBjects属性中。

我发生了许多有趣的事情。

1。)我不能为我的生活让List属性正常工作。我使用此列表来存储我的JSON。字符串值,然后是列表中每个项目的整个对象。你会注意到在JSONToStringList方法中,我清除了stringlist(它被注释掉了,因为它不是,我的程序挂起)

2。)在为多个JSON集需要多次调用方法后,我在列表中得到了重复的值

TConnector = class(TComponent)
  private
    { Private declarations }
    FList: TStrings; 
    procedure SetList(const Value: TStrings); 
  protected
    { Protected declarations }
  public
    { Public declarations }
    Constructor Create( AOwner : TComponent ); override;
    Destructor Destroy; Override;
    Procedure GenerateJSON;
    Procedure JSONToStringList(aJSonKey: String);
  published
    { Published declarations }
    property List: TStrings Read FList Write SetList; 

  end;


Constructor TConnector.Create(AOwner: TComponent);
begin
  inherited;
  FList:= TStringList.Create(True);
end;


destructor TConnector.Destroy;
begin
  if FList <> nil then
   FreeAndNil(FList);
  inherited;
end;

Procedure TConnector.GenerateJSON;
begin
if ResponseStream<>nil then
  Begin
  FreeAndNil(ResponseJSON_V);
  ResponseJSON_V := TJSONObject.ParseJSONValue(StreamToArray(ResponseStream),0) as TJSONValue;
  End;
end;

procedure TConnector.JSONToStringList(aJSonKey: String);
Var
  zLJsonValue  : TJSONValue;
  zLJSONArray: TJSONArray;
  zLJsonObject : TJSONObject;
  zI           : Integer;
begin
  if ResponseJSON_V is TJSONArray then
  begin
    zLJSONArray:= ResponseJSON_V as TJSONArray;
    zLJsonObject := zLJSONArray.Get(0) as TJSONObject;
  end
  else
  if ResponseJSON_V is TJSONObject then
  begin
    zLJSONArray:= nil;
    zLJsonObject := ResponseJSON_V as TJSONObject;
  end
  else
    Exit;
  if zLJSONArray<>nil then
  begin
     ***//FList.Clear;***
    for zLJsonValue in zLJSONArray do
    begin
      zLJsonObject := zLJsonValue as TJSONObject;
      for zI := 0 to zLJsonObject.Size-1 do
      begin
        if zLJsonObject.Get(zI).JsonString.Value = aJSonKey then
        begin
          FList.AddObject(zLJsonObject.Get(zI).JSONValue.Value, zLJsonObject);
        end;
      end;
    end;
  end
  else
  begin
    FList.Clear;
    for zI := 0 to zLJsonObject.Size-1 do
      begin
        if zLJsonObject.Get(zI).JsonString.Value = aJSonKey then
        FList.AddObject(zLJsonObject.Get(zI).JSONValue.Value, TJSONPair(zLJsonObject.Get(zI)));
      end;
  end;
end;

我希望这一切都是可以理解的。如果您需要了解更多信息,请与我们联系。请随意更正我在代码中看到的任何其他内容。我一直在学习:) - 谢谢你的帮助

3 个答案:

答案 0 :(得分:1)

  1. 如果FList.Clear挂起,则很可能是内存损坏问题。我怀疑的前两件事是你没有调用构造函数或者内存的那部分被其他东西覆盖了。

  2. 列表中的重复值是否可能是因为您注释掉了FList.Clear。无论如何,我建议使用调试器来查看列表中的内容或记录列表中添加/删除的所有内容。这可以让您了解列表中不需要的值来自何处。

  3. 作为一般建议,您不需要在释放之前检查对象是否为零。无论如何,检查是在Free(或FreeAndNil的Free部分)中进行的。

答案 1 :(得分:1)

事实证明,FList属性不应该已经发布,而是公开发布。从那以后,因为列表只在运行时填充和清空,从不在设计时。

TLiveConnector = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
     List: TStrings;  
  published
  end;

不确定为什么会出现这种情况,但现在似乎工作得很好

调用List.Clear而不是FList.Clear;

答案 2 :(得分:0)

你的代码无法正常工作......你定义了一个名为“aJSonKey”的param,你将它称为“ResponseJSON_V”进入程序。

此外,当没有这种方式调用属性时,你将这个“ResponseJSON_V”称为GenerateJSON proc。