用Delphi解析可空的TJSONObject

时间:2015-03-01 01:28:34

标签: json delphi

我使用的是Delphi XE3。我有一个JSON流,其中一个对象可以为null。也就是说,我可以收到:

"user":null

"user":{"userName":"Pep","email":"pep@stackoverflow.com"}

我想区分这两种情况,并尝试使用此代码:

var 
  jUserObject: TJSONObject;

jUserObject := TJSONObject(Get('user').JsonValue);
if (jUserObject.Null) 
then begin
  FUser := nil;
end else begin
  FUser := TUser.Create;
  with FUser, jUserObject do begin
    FEmail := TJSONString(Get('email').JsonValue).Value;
    FUserName := TJSONString(Get('userName').JsonValue).Value;
  end;
end;

如果我在第if (jUserObject.Null) then begin行放置一个断点并将鼠标放在jUserObject.Null上,如果jUserObject.Null = True它会显示"user":null,如果jUserObject.Null = False则显示"user":{"userName":"Pep","email":"pep@stackoverflow.com"} }}

但是,如果我使用调试器进入该行,jUserObject.Null将调用以下XE3库代码:

function TJSONAncestor.IsNull: Boolean;
begin
  Result := False;
end;

即使False,我的if句也总是"user":null

我想我总是有一个解决方法,即捕获在执行"user":nullGet('email').JsonValue时引发的异常,以便区分值是否为null,但这看起来并不那么优雅

如何判断JSON对象在JSON流中是否具有空值?

2 个答案:

答案 0 :(得分:5)

Get()返回TJSONPair。当您拥有"user":null时,TJSONPair.JsonValue属性将返回TJSONNull对象,而不是TJSONObject对象。你的代码没有考虑到这种可能性。它假定JsonValue始终为TJSONObject且未验证类型转换。

有两种方法可以解决这个问题。

  1. TJSONPair有自己的Null属性,用于指定其JsonValue是否为空值:

    var
      JUser: TJSONPair;
      jUserObject: TJSONObject;
    
    jUser := Get('user');
    if jUser.Null then begin
      FUser := nil;
    end else begin
      // use the 'as' operator for type validation in
      // case the value is something other than an object...
      jUserObject := jUser.JsonValue as TJSONObject;
      ...
    end;
    
  2. 使用is运算符在投射之前测试JsonValue的类类型:

    var
      JUser: TJSONPair;
      jUserObject: TJSONObject;
    
    jUser := Get('user');
    if jUser.JsonValue is TJSONNull then begin
      FUser := nil;
    end
    else if jUser.JsonValue is TJSONObject then begin
      jUserObject := TJSONObject(jUser.JsonValue);
      ...
    end else begin
      // the value is something other than an object...
    end;
    

答案 1 :(得分:3)

您犯了将JSON对象与Delphi对象混淆的常见错误。 TJSONObject类仅表示JSON对象,它们永远不会为空,因为null{...}不同。 TJSONObject不是所有JSON值的祖先,就像您的代码所假设的那样。 TJSONValue是。

不要输入你的用户"价值为TJSONObject,直到您知道它为对象。首先检查Null属性,然后输入类型。