使用 lkJSON 解析 JSON

Parse JSON using lkJSON

我有一个 JSON 文件,我需要解析并提取一个值。

{
  "user": {
    "pk": 25025320,
    "username": "instagram",
    "full_name": "Instagram",
    "is_private": false,
    "profile_pic_url": "https://instagram.fmad3-5.fna.fbcdn.net/vp/295f9e76d3c26fdf613d7856e7b43348/5B4F495B/t51.2885-19/s150x150/14719833_310540259320655_1605122788543168512_a.jpg",
    "profile_pic_id": "1360316971354486387_25025320",
    "is_verified": true,
    "has_anonymous_profile_picture": false,
    "media_count": 5164,
    "follower_count": 233901016,
    "following_count": 187,
    "biography": "Discovering — and telling — stories from around the world.",
    "external_url": "",
    "usertags_count": 144,
    "hd_profile_pic_versions": [
      {
        "width": 320,
        "height": 320,
        "url": "https://instagram.fmad3-5.fna.fbcdn.net/vp/893534d61bdc5ea6911593d3ee0a1922/5B6363AB/t51.2885-19/s320x320/14719833_310540259320655_1605122788543168512_a.jpg"
      }
    ],
    "hd_profile_pic_url_info": {
      "url": "https://instagram.fmad3-5.fna.fbcdn.net/vp/8ae8a89c80ff4722eeab592b685276cb/5B5D40A1/t51.2885-19/14719833_310540259320655_1605122788543168512_a.jpg",
      "width": 320,
      "height": 320
    },
    "has_highlight_reels": true,
    "auto_expand_chaining": false
  },
  "status": "ok"
}

我想使用 lkJSON library, Instagram API and code below to achievie this result.

提取 hd_profile_pic_url_info.url 的值并将其发送到 Memo2
var
  sJSON: string;
  js, Items, Item: TlkJSONbase;
  I, J: Integer;
begin
  sJSON := Memo1.text;
  js := TlkJSON.ParseText(sJSON);
  for I := 0 to Pred(js.Count) do
  begin
    Items := js.Child[I].Field['user'];
    for J := 0 to Pred(Items.Count) do
    begin
      Item := Items.Child[J];
      Memo2.Lines.Add(VarToStr(Item.Field['hd_profile_pic_url_info'].Value));
    end;
  end;
end;

我使用这个功能:

function ChildValueStr(AChild: TlkJSONbase; const Name: string; DefaultValue:
    AnsiString = ''): {$IF CompilerVersion>=26}WideString{$ELSE}AnsiString{$IFEND};
var
  tmpIndex: integer;
  tmpStr: {$IF CompilerVersion>=26}WideString{$ELSE}AnsiString{$IFEND};
begin
  Result:= DefaultValue;
  if IsNil(AChild) then exit;

  tmpStr:= (AChild as TlkJSONobject).{$IF CompilerVersion>=26}getWideString{$ELSE}getString{$IFEND}(Name);

  if tmpStr = '' then
  begin
    tmpIndex := (AChild as TlkJSONobject).IndexOfName(Name);
    if tmpIndex <> -1 then
      Result := (AChild as TlkJSONobject).getString(tmpIndex);
  end
  else Result:= tmpStr;
end;

所以对于你的代码,你可以使用它:

var sJSON: String;    
js, Items, Item: TlkJSONBase;    
I, J: Integer;    
begin    
    sJSON := Memo1.text;    
    js := TlkJSON.ParseText(sJSON);    
    for I := 0 to Pred(js.Count) do
    begin
        Items := js.Child[I].Field['user'];          
        Memo2.Lines.Add(ChildValueStr(Items, 'hd_profile_pic_url_info'));
    end;   
end;

希望对你有所帮助

您忘记了hd_profile_pic_url_info是另一个包含urlwidthheight的对象,所以您需要再往下看一次。这是正确执行此操作的示例。

var
  js : TlkJSONbase;
begin
  js := TlkJSON.ParseText(Memo1.Text);
  if Assigned(js) then
  begin
    js := js.Field['user'];
    if Assigned(js) then
    begin
      js := js.Field['hd_profile_pic_url_info'];
      if Assigned(js) then
      begin
        js := js.Field['url'];
        if Assigned(js) then
           Memo2.Lines.Add(VarToStr(js.Value));
      end;
    end;
  end;
end;

无需使用外部组件即可解析 JSON 的另一种方法是免费在线服务 https://jsontodelphi.com/

您粘贴 JSON 文本,它会生成一个带有 delphi 类 的单元来毫无问题地解析文本。如果 JSON 文本很复杂就更好了。

在这种情况下,访问值的代码最简单:

procedure TForm2.Button1Click(Sender: TObject);
var
  root:TRootClass;
begin
  root := TRootClass.FromJsonString(Memo1.Lines.Text {your JSON text});
  // The caption get the URL of the pic
  Caption := root.user.hd_profile_pic_url_info.url;
end;