【问题标题】:How to access nested values in JSON using X-SuperObject如何使用 X-SuperObject 访问 JSON 中的嵌套值
【发布时间】:2017-03-23 02:10:37
【问题描述】:

我想从这个 json 中获取所有用户。

{
  "status": "ok",
  "next_max_id": "AQAmA1l9NAQXa",
  "sections": [
    {
      "module": null,
      "show_view_all": null,
      "title": null,
      "users": [
        {
          "pk": 48165888,
          "is_verified": false,
          "profile_pic_url": "http://scontent-sit4-1.cdninstagram.com/t51.2885-19/s150x150/17332306_1915592632007479a.jpg",
          "full_name": "Jason Giovany Castro Morales",
          "is_private": false,
          "has_anonymous_profile_picture": false,
          "username": "jasongiovanycastromorales",
          "profile_pic_id": "14699765111792881_48165888"
        }
      ]
    }
  ]
}

现在,我尝试获取所有用户名。

procedure TForm2.Button6Click(Sender: TObject);
var
  json : ISuperObject;
  node : ISuperObject;
  item : IMember;
begin
  try
    json := TSuperObject.Create(list.Text);

    for item in json['sections.users'].AsArray do
    begin
      node := item.AsObject;
      Memo4.Lines.Add(node.S['username']);
    end;
  finally
  end;
end;

第二次尝试.. 我得到一个 AV !

var
    json         : ISuperObject;
    node         : ISuperObject;
    item, item2         : IMember;
  begin
     json := SO(list.Text);

   for item in json['sections'].AsArray do
    begin
       for item2 in json['users'].AsArray do
        begin
        node := item.AsObject;

        Memo1.Lines.Add(node.S['username']);
       end;
     end;
  end;

这个 JSON 中有 200 个用户名值 我什么也没得到,有时 AV 当我尝试使用 json 代码时,我的问题是,如何正确解析这个 json 以获得值username?谢谢。

【问题讨论】:

    标签: json delphi delphi-10-seattle xsuperobject


    【解决方案1】:

    您的示例已损坏并且您没有指定输入数据的格式,就像我不知道sections 数组中的所有对象是否包含users 数组一样。无论如何,这个例子应该适用于你的 sn-p。

    SuperObject

    procedure TForm2.Button6Click(Sender: TObject);
    var
      json, user, section : ISuperObject;
    begin
      json := SO(list.Text);
      for section in json['sections'] do
      begin
        if Assigned(section['users']) then
        begin
          for user in section['users'] do
          begin
            if user.S['username'] <> '' then
              Memo4.Lines.Add(user.S['username']);
          end;
        end;
      end;
    end;
    

    编辑: 实际上,您使用的不是SuperObject,而是X-SuperObject,这是不同的东西。即使我从未使用过该库,我也只能通过他们网站上的示例找到问题,因为您会犯一些简单的错误,例如在第二个循环中使用 item 而不是 item2jsonitem .

    X-SuperObject

    procedure TForm2.Button6Click(Sender: TObject);
    var
      json : ISuperObject;
      item, item2 : IMember;
    begin
      json := TSuperObject.Create(list.Text);
      for item in json['sections'].AsArray do
      begin
        for item2 in item.AsObject['users'].AsArray do
          Memo1.Lines.Add(item2.AsObject['username'].ToString);
      end;
    end;
    

    【讨论】:

    • 错误or-in statement cannot operate on collection type 'ISuperExpression' because 'ISuperExpression' does not contain a member for 'GetEnumerator', or it is inaccessible
    • 编辑了我的答案。您真的应该更加注意您使用的变量并明确说明问题。
    • 我的错,我认为 X-SuperObject 只是对 SuperObject 的升级,非常感谢兄弟
    【解决方案2】:

    免责声明:此答案与SuperObject 有关。当时给出了这个答案,不知道这个问题究竟是指XSuperObject


    我一无所获

    这不太可能,因为您至少应该遇到访问冲突。这是因为,您没有以正确的方式创建超级对象。

    我建议你使用工厂函数SO(),而不是调用构造函数TSuperObject.Create

    那么你必须记住sectionsusers 都是数组。因此,您需要在嵌套迭代中迭代两个数组:

    var
      json: ISuperObject;
      section: ISuperObject;
      user: ISuperObject;
    begin
      json := SO(list.Text);
      for section in json['sections'] do // iterate sections
        for user in section['users'] do  // iterate users
          Memo4.Lines.Add(user.S['username']);
     end;
    

    注意:这个例子是一个最小的方法。您应该添加进一步检查(例如Assigned())以防止异常。

    【讨论】:

    • for-in statement cannot operate on collection type 'ISuperExpression' because 'ISuperExpression' does not contain a member for 'GetEnumerator', or it is inaccessible,这就是我使用IMember的原因
    • 如果之前没有经过编译和测试,我不会发布我的答案。我没有这样的错误。 ISuperExpression 来自哪里?我的代码专门迭代ISuperObject 的枚举器,它返回ISuperObjects。
    • 就在这一行for section in json['sections'] do // iterate sections
    • 您使用哪个版本的 SuperObject?当我查看ISuperObject 的声明时,有property O[const path: SOString]: ISuperObject read GetO write PutO; default;。因此,json['sections'] 的返回值也是ISuperObject 类型。 for..in-loop 需要一个枚举器,它通过其方法function GetEnumerator: TSuperEnumerator;ISuperObject 返回。查看TSuperEnumerator 的声明,再次返回了ISuperObject (property Current: ISuperObject)。见:github.com/hgourvest/superobject/blob/master/superobject.pas
    猜你喜欢
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多