【问题标题】:Parsing\iterating thru JSON `bad` arrays in javascript with jquery. Ho to parse such thing?使用 jquery 在 javascript 中通过 JSON `bad` 数组解析\迭代。何来解析这样的事情?
【发布时间】:2011-07-12 19:07:38
【问题描述】:

我从我的服务器返回了 JSON,例如:

 {
    "user": {
        "nickname": "Ann",
        "width": 90,
        "height": 60
    },
    "user": {
        "nickname": "Dan",
        "width": 60,
        "height": 90
    }
}

我需要遍历所有用户,例如提醒昵称,所以我尝试下一个代码:

var obj = jQuery.parseJSON('{    "user": {        "nickname": "ole",        "width": 333,        "height": 222    },    "user": {        "nickname": "jak",        "width": 333,   "height": 222 }}');
for (user in obj ) {
   alert( obj[user][nickname]);
}

失败了。我该怎么做才能提醒所有用户名(我无法更改服务器返回json的方式=(所以我希望在JS端找到解决方案。)

代码是dying alive here.

【问题讨论】:

    标签: javascript jquery arrays json


    【解决方案1】:

    你遇到的问题是你有一个数组和数组。你需要使用类似的东西

    var obj = jQuery.parseJSON('[ {"user": {        "nickname": "ole",        "width": 333,        "height": 222    }},    {"user": {        "nickname": "jak",        "width": 333,   "height": 222 }}]');
    for (i=0;i<obj.length;i++) {
         alert(obj[i].user.nickname);
    }
    

    每个“用户”都是数组的一部分,即 0,1...

    另外,正如其他人指出的那样。您需要将名称放在引号中。

    最后,JSON 是错误的。如您所见,它应该包含数组括号。此代码有效。您可以在www.json.org 引用格式良好的 JSON。最终,如果您想迭代用户,服务器将不得不为您提供有效的 JSON。

    【讨论】:

    • 试试上面的代码。 JSON 在解析时“错误”,您只能查看第一个 USER。 Chrome 调试器指出了这一点,如果您对原始对象执行 console.log(obj),则只有一个“用户”出现,因为 JSON 错误。
    【解决方案2】:

    老实说,如果您想可靠地做到这一点,您可以修改现有的纯 JS JSON 解析器。例如,看看 Douglas Crockford 的简单递归下降解析器“parse_json”:https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js

    第 272 行(在对象函数中)我们有:

    if (Object.hasOwnProperty.call(object, key)) {
        error('Duplicate key "' + key + '"');
    }
    object[key] = value();
    

    我们可以将其替换为:

    if (Object.hasOwnProperty.call(object, key)) {
         if (Object.hasOwnProperty.call(dupKeys, key) && dupKeys[key]) {
             object[key].push(value());
         } else {
             object[key] = [ object[key], value() ];
             dupKeys[key] = true;
         }
    } else {
         object[key] = value();
    }
    

    当然,在第 259 行左右,我们必须添加变量 dupKeys,

    var key,
        object = {},
        dupKeys = {};
    

    然后 json_parse 会解析你的 JS。

    var obj = json_parse("... your bad JSON here ...");
    obj.user.forEach(function(user) {
        alert(user["nickname"]);
    });
    

    【讨论】:

    • 顺便说一句:在官方 JSON 规范中重复键是非法的吗?
    • 是的。尽管语法没有明确禁止它,但我认为您不会找到可以按照您想要的方式解析它的有效解析器。对我来说,正确的行为是用新值覆盖键上的前一个条目。然而,道格拉斯·克罗克福德是男人,很难说。
    【解决方案3】:

    将昵称更改为“昵称”,因为您没有为它定义变量:

    alert( obj[user]["nickname"]);
    

    【讨论】:

      【解决方案4】:

      由于您无法更改 JSON 服务器端,因此您需要在解析之前更改它的客户端。

      鉴于提到的 JSON,您可以使用此功能:

      function fixData( d ) {
          d = d.replace(/,\s*\"user\"\:/, ",");
          d = d.replace(/\"user\"\:/, "\"users\":[");
          d = d.replace(/}\s*$/, "]}");
          return d;
      }
      

      在运行parseJSON 之前,只需通过以下方式“修复”JSON:

      var obj = jQuery.parseJSON(fixData(/* JSON string */));
      

      Fiddle with my solve

      如果你想遍历每个用户并输出“昵称”:

      jQuery.each(obj.users, function(){ alert(this.nickname); });
      

      请注意:显然fixData 函数中的正则表达式是脆弱的,不应该用作任何其他数据源的通用解决方案;如果不完全匹配,您需要将其重写为您的特定用例。

      【讨论】:

      • 另外,我强烈建议您修改服务器端 JSON 响应(类似于 @patrick_dw 的建议),因为它是无效的。在那天之前,它只能用作垫片。
      【解决方案5】:

      有两个问题。

      首先,键必须是唯一的。您在同一对象符号中使用了两次密钥 user。最好使用数组表示法。

      其次,[nickname] 应该是.nickname["nickname"]

      var json = '{    "user": {        "nickname": "ole",        "width": 333,        "height": 222    },    "user": {        "nickname": "jak",        "width": 333,   "height": 222 }}';
      
         // make it an Array
      json = '[' + json.slice(1,-1).replace(/"user":/g,'') + ']';
      
      var obj = $.parseJSON( json );
      
      for (var i = 0, len = obj.length; i < len; i++ ) {
         alert( obj[i].nickname);
      }
      

      示例: http://jsfiddle.net/z7YxR/

      【讨论】:

      • 是否可以使用唯一的user 键解决该问题?
      • @Kabumbus:我更新了我的答案。是的,因为他们都是用户,所以您不需要将每个人都标记为“用户”。只需使用数组表示法,它将被解析为带有数字索引的 JavaScript 数组。
      • @Kabumbus:刚刚注意到您无法修复标记服务器端。我已经更新以显示如何在客户端上修复它。
      • @patrick dw 在修复服务器端数据时可能是他最终需要做的事情,服务器端代码仍然是无效的 JSON 数据真的很糟糕。另一端的人需要解决这个问题。世界上已经有足够多的糟糕代码了,弥补它是愚蠢的。 :)
      猜你喜欢
      • 2018-05-28
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多