Delphi JsonTextReader无法读取值

时间:2017-09-14 23:15:26

标签: json delphi

我有一个非常奇怪的情况。

这是我试图解析的JSON:

[
  {
    "username":"xxx",
    "email":"xxx@gmail.com",
    "custom_title":"xxx title",
    "timezone":"Africa\/Cairo",
    "message_count":"218",
    "alerts_unread":"0",
    "like_count":"385",
    "friend_count":"0"
  }
]

这是我的解析代码:

type
  TUserData = record
    email, timezone: string;
    msg, alerts, likes: integer;
 end;

procedure TDMRest.parseData(var b: TUserData);
var
  jtr: TJsonTextReader;
  sr: TStringReader;
begin
  //RESTResponseLogin.Content has the above json text
  sr := TStringReader.Create(RESTResponseLogin.Content);
  try
    jtr := TJsonTextReader.Create(sr);
    try
      while jtr.Read do
      begin
        if jtr.TokenType = TJsonToken.StartObject then
          process(b, jtr);
      end;
    finally
      jtr.Free;
    end;
  finally
    sr.Free;
   end;
end;

//here there is a problem
procedure TDMRest.process(var c: TUserData; jtr: TJsonTextReader);
begin
  while jtr.Read do
  begin
    if (jtr.TokenType = TJsonToken.PropertyName) then
    begin
      if jtr.Value.ToString = 'email' then
      begin
        jtr.Read;
        c.email := jtr.Value.AsString;
      end;

      if jtr.Value.ToString = 'timezone' then
      begin
        jtr.Read;
        c.timezone := jtr.Value.AsString;
      end;

      if jtr.Value.ToString = 'message_count' then
      begin
        jtr.Read;
        c.msg := jtr.Value.AsInteger;
      end;

      if jtr.TokenType = TJsonToken.EndObject then
      begin
        c.alerts := 0;
        c.likes := 0;
        exit;
      end;
    end;
  end;
end;

我的问题:在process()代码中,前两个if块(emailtimezone)可以将值读入我的记录。但是当我添加其他if块(例如if jtr.Value.ToString = 'message_count' then)时,我再也看不到记录的值了。

我是否正确解析数据?

基本上,我需要从JSON字符串中获取信息并将数据放在TUserData记录中。

我在一本名为“Expert Delphi”的书中找到了上述模式,我很确定parseData()函数是正确的。可能我在这个过程中遗漏了一些东西。

TDMRrst是一个DataModule;我给函数一个记录,我想要正确解析数据。

这里有什么问题?

1 个答案:

答案 0 :(得分:3)

在您显示的JSON中,所有值都是字符串,没有整数。因此,当您为jtr.Value.AsInteger值调用message_count时,会引发您未捕获的转换异常。 TValue.AsInteger不会为您执行从字符串到整数的隐式转换。

您必须使用jtr.Value.AsString,并使用StrToInt()将字符串转换为整数:

if jtr.Value.ToString = 'message_count' then
begin
  jtr.Read;
  //c.msg := jtr.Value.AsInteger;
  c.msg := StrToInt(jtr.Value.AsString);
end;

对JSON中的其他“整数”值执行相同操作(alerts_unreadlike_countfriend_count)。