【问题标题】:Parsing JSON in JavaScript using for loop使用 for 循环在 JavaScript 中解析 JSON
【发布时间】:2011-04-19 11:55:34
【问题描述】:

A]问题总结:

我有 JSON 数据从 python 返回到 javascript。我想通过 JSON 结构并在 html 表中打印数据元素。

B] 代码摘录:

1] 从 python 返回的 JSON --

{'data_for_users_city': 
 '[
    {"city": 
            {"city_name": "Boston", 
             "country": {"country_name": "United States"}
            },
            "status": true, 
            "date_time": {"ctime": "Thu Apr  7 09:38:00 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 0, "microsecond": 796000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 0, 3, 97, -1], "year": 2011, "epoch": 1302169080.0, "isoformat": "2011-04-07T09:38:00.796000", "day": 7, "minute": 38}
    },
  ]'
}

注意这是一个单一的城市,像这样在 JSON 数据中有很多城市元素。

2] 我尝试通过数据结构解析并打印预先准备好的 HTML 表“#datatable_for_current_users”的“tbody”中的数据元素的 Javascript 代码

function LoadUsersDatatable(data) {
   var tbody = $("#datatable_for_current_users > tbody").html("");

   for (var i=0; i < data.length; i++) 
    {
      var city = data.data_for_users_city[i];
        var rowText = "<tr class='gradeA'><td>" + city.county.country_name + "</td><td>" + city.city_name + "</td><td>" + city.status + "</td><td>" + city.date_time.ctime + "</td></tr>";

          $(rowText).appendTo(tbody);
 }
}    

我有 javascript 代码的问题是:

1] 我无法在“数据”中找到城市元素的确切长度,因此我不知道 for 循环的上限是多少

2] 我不确定我是否在 for 循环中正确访问了“city”变量。

[编辑#1]

根据 Salman 和 Pointy 给出的响应,我必须检查返回 json 数据的 python 代码。经过一番调试,发现 JSON 数据是使用模板返回的,因此模板名称出现在 JSON 数据中。我更改了发送 JSON 的机制,现在返回的 JSON 数据如下所示

[{"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 1, "status": true, "date_time": {"ctime": "Thu Apr  7 09:38:00 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 0, "microsecond": 796000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 0, 3, 97, -1], "year": 2011, "epoch": 1302169080.0, "isoformat": "2011-04-07T09:38:00.796000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 2, "status": false, "date_time": {"ctime": "Thu Apr  7 09:38:03 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 3, "microsecond": 359000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 3, 3, 97, -1], "year": 2011, "epoch": 1302169083.0, "isoformat": "2011-04-07T09:38:03.359000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 3, "status": true, "date_time": {"ctime": "Thu Apr  7 09:38:08 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 8, "microsecond": 281000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 8, 3, 97, -1], "year": 2011, "epoch": 1302169088.0, "isoformat": "2011-04-07T09:38:08.281000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 4, "status": false, "date_time": {"ctime": "Thu Apr  7 09:38:14 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 14, "microsecond": 578000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 14, 3, 97, -1], "year": 2011, "epoch": 1302169094.0, "isoformat": "2011-04-07T09:38:14.578000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 13, "status": true, "date_time": {"ctime": "Wed Apr 13 01:37:58 2011", "hour": 1, "isoweekday": 3, "month": 4, "second": 58, "microsecond": 343000, "isocalendar": [2011, 15, 3], "timetuple": [2011, 4, 13, 1, 37, 58, 2, 103, -1], "year": 2011, "epoch": 1302658678.0, "isoformat": "2011-04-13T01:37:58.343000", "day": 13, "minute": 37}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 14, "status": false, "date_time": {"ctime": "Wed Apr 13 01:38:01 2011", "hour": 1, "isoweekday": 3, "month": 4, "second": 1, "microsecond": 78000, "isocalendar": [2011, 15, 3], "timetuple": [2011, 4, 13, 1, 38, 1, 2, 103, -1], "year": 2011, "epoch": 1302658681.0, "isoformat": "2011-04-13T01:38:01.078000", "day": 13, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 23, "status": true, "date_time": {"ctime": "Sun Apr 17 21:24:18 2011", "hour": 21, "isoweekday": 7, "month": 4, "second": 18, "microsecond": 625000, "isocalendar": [2011, 15, 7], "timetuple": [2011, 4, 17, 21, 24, 18, 6, 107, -1], "year": 2011, "epoch": 1303075458.0, "isoformat": "2011-04-17T21:24:18.625000", "day": 17, "minute": 24}}]

我仍在努力围绕这个 json 结构进行 for 循环。

[编辑#2]

经过@Salman 的一些调试和响应,下面的函数完成了这项工作

function LoadUsersDatatable(data) {
                                   var tbody = $("#datatable_for_current_users > tbody").html(""); 
                                   jsonData = jQuery.parseJSON(data);

                                   for (var i = 0; i < jsonData.length; i++) 
                                    {
                                        var citydata = jsonData[i];
                                        var rowText = "<tr class='gradeA'><td>" + citydata.city.country.country_name + "</td><td>" + citydata.city.city_name + "</td><td>" + citydata.status + "</td><td>" + citydata.date_time.ctime + "</td></tr>";
                                        $(rowText).appendTo(tbody);
                                    }

                                }    

我在调试时发现的一个问题是返回的 JSON 是字符串格式,必须转换为 JSON 对象,这是使用 jQuery 完成的。

【问题讨论】:

  • 在解析您发布的代码时出现“未终止的字符串文字”错误。这是复制粘贴错误吗?
  • 那不是 JSON。 jsonlint.com(您可能希望 data_for_users_city 的值是一个数组,而不是字符串)
  • 正如@David Dorward 所说,您的“JSON”无效。首先,所有引用都必须使用双引号,而不是单引号。其次,这与其说是“无效”,不如说是错误,“data_for_users_city”的值真的不应该像那样被完全引用——它违背了使用 JSON 作为编码的全部目的。
  • @Salman 和@Pointy,你们都是正确的,从 python 编写的 JSON 稍微无效,因为它是使用“模板”返回的。我修改了返回 JSON 值的机制,我可以看到 JSON 是有效的。我通过这个站点 jsonformatter.curiousconcept.com 传递了我的 JSON 对象,它显示它们是有效的。我将很快发布字符串和原始 for 循环的结果。
  • @Salman 和@Pointy,首先非常感谢您查看 JSON 数据。我修改了 python 代码,返回的 JSON 数据出现在主帖的“EDIT#1”部分。

标签: javascript html json


【解决方案1】:

您似乎在使用 jQuery。如果您想直接从 JSON 数据生成 HTML,一种简单的解决方案是通过插件使用简单的模板,例如 jQote2。它提供了一种简单的语法,可以遍历您的数据。使用 JS 模板还可以更轻松地维护您的 HTML 结构。

【讨论】:

    【解决方案2】:

    奇怪,data_for_users_city 似乎不是数组而是一个字符串。我希望这不是拼写错误或复制/粘贴错误。

    编辑 1

    即使您将其视为字符串,您的 JSON 仍然有错误。 JavaScript 中不允许引号内的换行符,您必须用\n 替换它们,使用+ 连接运算符或使用\ 将字符串拆分为多行。如果您设法解决这些问题,您可以执行以下操作:

    var data_for_users_city = eval(data.data_for_users_city);
    // sometimes adding extra parenthesis help
    // var data_for_users_city = eval('(' + data.data_for_users_city + ')');
    alert(data_for_users_city.length);
    

    编辑 2

    这是我在 FireFox/Firebug 控制台中创建和测试的快速而肮脏的演示。它基本上演示了如何访问 JSON 中的三个级别的数据。要正确可视化您的 JSON 数据,请复制以下代码并粘贴到 jsbeautifier

    var data = [{"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 1, "status": true, "date_time": {"ctime": "Thu Apr  7 09:38:00 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 0, "microsecond": 796000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 0, 3, 97, -1], "year": 2011, "epoch": 1302169080.0, "isoformat": "2011-04-07T09:38:00.796000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 2, "status": false, "date_time": {"ctime": "Thu Apr  7 09:38:03 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 3, "microsecond": 359000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 3, 3, 97, -1], "year": 2011, "epoch": 1302169083.0, "isoformat": "2011-04-07T09:38:03.359000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 3, "status": true, "date_time": {"ctime": "Thu Apr  7 09:38:08 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 8, "microsecond": 281000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 8, 3, 97, -1], "year": 2011, "epoch": 1302169088.0, "isoformat": "2011-04-07T09:38:08.281000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 4, "status": false, "date_time": {"ctime": "Thu Apr  7 09:38:14 2011", "hour": 9, "isoweekday": 4, "month": 4, "second": 14, "microsecond": 578000, "isocalendar": [2011, 14, 4], "timetuple": [2011, 4, 7, 9, 38, 14, 3, 97, -1], "year": 2011, "epoch": 1302169094.0, "isoformat": "2011-04-07T09:38:14.578000", "day": 7, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 13, "status": true, "date_time": {"ctime": "Wed Apr 13 01:37:58 2011", "hour": 1, "isoweekday": 3, "month": 4, "second": 58, "microsecond": 343000, "isocalendar": [2011, 15, 3], "timetuple": [2011, 4, 13, 1, 37, 58, 2, 103, -1], "year": 2011, "epoch": 1302658678.0, "isoformat": "2011-04-13T01:37:58.343000", "day": 13, "minute": 37}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 14, "status": false, "date_time": {"ctime": "Wed Apr 13 01:38:01 2011", "hour": 1, "isoweekday": 3, "month": 4, "second": 1, "microsecond": 78000, "isocalendar": [2011, 15, 3], "timetuple": [2011, 4, 13, 1, 38, 1, 2, 103, -1], "year": 2011, "epoch": 1302658681.0, "isoformat": "2011-04-13T01:38:01.078000", "day": 13, "minute": 38}}, {"city": {"city_name": "Framingham", "country": {"country_name": "United States", "id": null}, "id": null}, "id": 23, "status": true, "date_time": {"ctime": "Sun Apr 17 21:24:18 2011", "hour": 21, "isoweekday": 7, "month": 4, "second": 18, "microsecond": 625000, "isocalendar": [2011, 15, 7], "timetuple": [2011, 4, 17, 21, 24, 18, 6, 107, -1], "year": 2011, "epoch": 1303075458.0, "isoformat": "2011-04-17T21:24:18.625000", "day": 17, "minute": 24}}];
    var table = $("<table border='1'/>");
    var thead = $("<thead/>")
        .appendTo(table);
    $("<tr/>")
        .append("<th>Country</th>")
        .append("<th>City</th>")
        .append("<th>Status</th>")
        .append("<th>Time</th>")
        .appendTo(thead);
    var tbody = $("<tbody/>")
        .appendTo(table);
    for (var i = 0; i < data.length; i++) {
        var citydata = data[i];
        $("<tr/>")
            .append("<td>" + citydata.city.country.country_name + "</td>")
            .append("<td>" + citydata.city.city_name + "</td>")
            .append("<td>" + citydata.status + "</td>")
            .append("<td>" + citydata.date_time.ctime + "</td>")
            .appendTo(tbody);
    }
    //
    // FOR TESTING
    //
    $("body").append(table);
    

    【讨论】:

    • @Salman A 我没有投反对票,但我怀疑有人可能对使用“eval()”的建议不满意。因为你指出了数据的严重问题,事实上,我赞成:-)
    • 是的。如果 eval 是(曾经)我建议使用 jQuery.parseJSON() 的问题。
    • @Salman,你是对的。 JSON 数据不正确。我已经修改了返回 JSON 代码的 python 代码,我的原始帖子的 EDIT#1 包含现在返回到 javascript 的 JSON 字符串。
    • @Salman,感谢您的回复。我已经使用了您给出的逻辑,并在我的主要帖子的“EDIT#2”部分粘贴了对我有用的最终解决方案。感兴趣的一项是 python 的返回值是一个字符串,因此需要使用 jquery 将其转换为 JSON。
    【解决方案3】:

    您是否考虑过使用 Javascript 模板引擎将 JSON 转换为 HTML?

    我是pure.js 的作者,它非常原创,但是有很多经典的双括号引擎可用。

    【讨论】:

      【解决方案4】:

      如果您使用 jQuery,请考虑使用 var json = $.parseJSON(data)。这会将您的 JSON 字符串转换为 JSON 对象。

      试试看。它应该会让你更容易找到你的对象。

      【讨论】:

        猜你喜欢
        • 2015-05-05
        • 1970-01-01
        • 2012-09-30
        • 1970-01-01
        • 2017-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        相关资源
        最近更新 更多