Delphi JSON解析器

8

我的当前代码:

procedure TForm1.Button10Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
  JSON: string;
  jsonObiekt: TJSONObject;
  streams: TJSONValue;
  liczbaStrumieni: integer;
  i: integer;
begin
  IdHTTP := TIdHTTP.Create;
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
    IdHTTP.IOHandler := IdSSL;
    IdHTTP.Request.CustomHeaders.AddValue('Accept', 'application/vnd.twitchtv.v3+json');
    IdHTTP.Request.CustomHeaders.AddValue('Client-ID', 'smb61nyd0vxmqdn9d3k735qbx41cdyg');
    JSON := IdHTTP.Get('https://api.twitch.tv/kraken/streams?game=StarCraft:%20Brood%20War');
  finally
    IdHTTP.Free;
  end;
  jsonObiekt := nil;
  try
    jsonObiekt := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(JSON), 0) as TJSONObject;
    streams := jsonObiekt.Get('streams').JsonValue;
    liczbaStrumieni := TJSONArray(streams).Size;
    for i := 0 to liczbaStrumieni - 1 do
    begin
      Memo6.Lines.Add(TJSONObject(TJSONArray(streams).Get(i)).Get('viewers').JsonValue.Value);
    end;
  finally
    jsonObiekt.Free;
  end;
end;

使用这段代码,我可以获取"streams"中所有条目的观看者信息。 enter image description here

我的目标是从"channel"中获取"status",但这对我来说太难了。尝试学习了这个链接How to parse nested JSON object in Delphi XE2?,但没有结果,还是不理解。感谢帮助。

1个回答

10

将子对象分解成它们自己的变量有助于简化代码,不要试图在一个语句中完成所有操作。尝试这样做:

procedure TForm1.Button10Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
  JSON: string;
  jsonObiekt: TJSONObject;
  streams: TJSONArray;
  stream: TJSONObject;
  channel: TJSONObject;
  status: TJSONString;
  liczbaStrumieni: integer;
  i: integer;
begin
  IdHTTP := TIdHTTP.Create;
  try
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
    IdHTTP.IOHandler := IdSSL;
    IdHTTP.Request.Accept := 'application/vnd.twitchtv.v3+json';
    IdHTTP.Request.CustomHeaders.AddValue('Client-ID', 'smb61nyd0vxmqdn9d3k735qbx41cdyg');
    JSON := IdHTTP.Get('https://api.twitch.tv/kraken/streams?game=StarCraft:%20Brood%20War');
  finally
    IdHTTP.Free;
  end;
  jsonObiekt := TJSONObject.ParseJSONValue(JSON) as TJSONObject;
  try
    streams := jsonObiekt.Get('streams').JsonValue as TJSONArray;
    liczbaStrumieni := streams.Size;
    for i := 0 to liczbaStrumieni - 1 do
    begin
      stream := streams.Get(i) as TJSONObject;
      channel := stream.Get('channel').JsonValue as TJSONObject;
      status := channel.Get('status').JsonValue as TJSONString;
      Memo6.Lines.Add(status.Value);
    end;
  finally
    jsonObiekt.Free;
  end;
end;

或者,以字节形式下载 JSON,这样 TIdHTTP 就不会将其解码为 UTF-16,因此 TJSONObject 可以按原样解析原始字节:

Alternatively, download the JSON as bytes so TIdHTTP will not decode them to UTF-16, and thus TJSONObject can parse the original bytes as-is:
procedure TForm1.Button10Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  IdSSL: TIdSSLIOHandlerSocketOpenSSL;
  JSON: TBytesStream;
  jsonObiekt: TJSONObject;
  streams: TJSONArray;
  stream: TJSONObject;
  channel: TJSONObject;
  status: TJSONString;
  liczbaStrumieni: integer;
  i: integer;
begin
  jsonObiekt := nil;
  try
    JSON := TBytesStream.Create;
    try
      IdHTTP := TIdHTTP.Create;
      try
        IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
        IdHTTP.IOHandler := IdSSL;
        IdHTTP.Request.Accept := 'application/vnd.twitchtv.v3+json';
        IdHTTP.Request.CustomHeaders.AddValue('Client-ID', 'smb61nyd0vxmqdn9d3k735qbx41cdyg');
        IdHTTP.Get('https://api.twitch.tv/kraken/streams?game=StarCraft:%20Brood%20War', JSON);
      finally
        IdHTTP.Free;
      end;
      jsonObiekt := TJSONObject.ParseJSONValue(JSON.Bytes, 0, JSON.Size) as TJSONObject;
    finally
      JSON.Free;
    end;
    streams := jsonObiekt.Get('streams').JsonValue as TJSONArray;
    liczbaStrumieni := streams.Size;
    for i := 0 to liczbaStrumieni - 1 do
    begin
      stream := streams.Get(i) as TJSONObject;
      channel := stream.Get('channel').JsonValue as TJSONObject;
      status := channel.Get('status').JsonValue as TJSONString;
      Memo6.Lines.Add(status.Value);
   end;
  finally
    jsonObiekt.Free;
  end;
end;

TBytesStream,缺少一个's'。 - TridenT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接