【问题标题】:Parsing malformed JSON with Javascript使用 Javascript 解析格式错误的 JSON
【发布时间】:2011-07-31 01:13:25
【问题描述】:

我想使用 Javascript 解析 this content。数据如下所示:

{"ss":[["Thu","7:00","Final",,"BAL","19","ATL","20",,,"56808",,"PRE4","2015"],["Thu","7:00","Final",,"NO","10","GB","38",,,"56809",,"PRE4","2015"]]}

每个在线教程都教你如何使用 Twitter 解析 JSON,但我不太确定使用 JSON 解析是如何工作的。

我想在一个网站上进行设置,以查看 NFL 球队的得分,这是一个有趣的项目和关于解析 JSON 的良好学习体验,因为我不太关心 Twitter 的东西。

这可能吗?有什么好的教程可以开始吗?甚至是一些起始代码?

【问题讨论】:

    标签: javascript json parsing


    【解决方案1】:

    一般来说,您可以使用JSON.parse 来执行此操作。但是,您拥有的那个 sn-p 似乎不是严格有效的 JSON(如此处所示:http://jsfiddle.net/yK3Gf/ 并且还通过在此处验证源 JSON:http://jsonlint.com/)。

    所以你要么需要手动解析它,要么让 nfl.com 修复他们的 JSON。

    作为替代方案,他们的 JSON 在使用 eval() 时会成功解析,因此您可以使用以下内容对其进行解析:

    var parsedData = eval('(' + jsonData + ')');
    

    ...如图所示:http://jsfiddle.net/yK3Gf/1/

    虽然请注意,以这种方式解析 JSON 通常是不受欢迎的(尤其是当被解析的数据是由第三方来源提供时),因为如果数据碰巧包含任何可执行文件,它会使您容易受到 XSS 攻击里面的代码。

    【讨论】:

    • 您可以使用Crockford's eval guard 来阻止脚本执行。我总是这样做。
    • 很棒的建议,我将在学习的过程中暂时使用这种方法。
    【解决方案2】:

    我处于类似的位置 - 非 javascript 专家正在从事一个有趣的项目以熟悉 javascript、ajax 和 json。

    我采取了三个不同的步骤来处理这个问题。我欢迎任何有关改进解决方案的反馈。

    第一步是查询nfl站点以下拉分数。由于 json 的来源(即 nfl 站点)与您的站点不同,因此您必须解决针对跨域查询的 javascript 安全约束。我发现这个stackoverflow link 是一个很好的参考。我使用 JSONP 作为解决方法。我使用http://whateverorigin.org/ 作为间接站点。

    $.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://www.nfl.com/liveupdate/scorestrip/scorestrip.json') + '&callback=?', handleQueryForScoresResult);
    

    正如其他人指出的那样,nfl 站点返回无效的 json 数据。以下示例行说明了该问题:

    ["Sun","4:25","Final",,"TEN","7","MIN","30",,,"55571",,"REG5","2012"] ,

    注意空数组元素值(中间没有数据的重复逗号)。所以在我的 json 回调函数中,我通过在调用 jquery 解析 json 数据之前将空字符串(两个双引号)添加到重复的逗号来更正数据:

    function handleQueryForScoresResult(data) {
        var jsonStr = data.contents;
        jsonStr = jsonStr.replace(/,,/g, ',"",');
        jsonStr = jsonStr.replace(/,,/g, ',"",');
    
        var scoresData = jQuery.parseJSON(jsonStr).ss;
        .
        .
        .
    }
    

    最后,我创建了 GameScores 对象来封装 json 数据。

    function GameScore(scoreData) {
        this.scoreData = scoreData;
        scoreData[2] = scoreData[2].toLowerCase();
        scoreData[5] = parseInt(scoreData[5]);
        scoreData[7] = parseInt(scoreData[7]);
    } 
    
    function GameScore_getAwayTeam() { return this.scoreData[4]; }
    function GameScore_getHomeTeam() { return this.scoreData[6]; } 
    function GameScore_isFinal() { return this.scoreData[2]=="final"; }  
    function GameScore_getHomeTeamScore() { return this.scoreData[7]; }
    function GameScore_getAwayTeamScore() { return this.scoreData[5]; }
    function GameScore_doesHomeTeamLead() { return this.scoreData[7]> this.scoreData[5]; }
    function GameScore_doesAwayTeamLead() { return this.scoreData[5]> this.scoreData[7]; }
    function GameScore_getWeekId() { return this.scoreData[12]; }
    
    GameScore.prototype.getHomeTeam = GameScore_getHomeTeam;
    GameScore.prototype.getAwayTeam = GameScore_getAwayTeam;
    GameScore.prototype.isFinal = GameScore_isFinal;
    GameScore.prototype.getHomeTeamScore = GameScore_getHomeTeamScore;
    GameScore.prototype.getAwayTeamScore = GameScore_getAwayTeamScore;
    GameScore.prototype.doesHomeTeamLead = GameScore_doesHomeTeamLead;
    GameScore.prototype.doesAwayTeamLead = GameScore_doesAwayTeamLead;
    GameScore.prototype.getWeekId = GameScore_getWeekId;
    

    我只添加了一些访问器,因为我不需要大部分数据。您的需求可能会有所不同。

    【讨论】:

    • 非常感谢肮脏的 JSON 清理帮助......这个 NFL API 让我很生气。穆乔·格拉西亚斯!
    【解决方案3】:

    我们使用 mootools 来处理类似的事情,但您也可以使用纯 JavaScript:http://www.json.org/js.html

    【讨论】:

      【解决方案4】:

      假设您已经有一个有效的 JSON String (jsonString) 来解析。 (如果您不知道如何检索 String 以使用给定 url 中的 XMLHttpRequest 进行解析,则必须先查看。)


      如果没有原生实现,您将不得不添加 Douglas Crockford 的 JSON 库(或类似的东西)以提供解析 Function,使用纯 JavaScript:

      var json = json_parse(jsonString) ;
      

      对于像 jQuery 这样的 JavaScript 库,这将是

      var json = $.parseJSON(jsonString) ;
      

      现在,遍历生成的 JSON Object 完全是另一个问题,因为您必须先了解其结构,然后才能检索特定数据。 在这种特殊情况下——如果它确实格式正确——你必须执行以下操作:

      var data = json.ss ;
      
           for(var i = 0 ; i < data.length ; i++) {
      
                var entry = data[i] ;
      
                var day = entry[0] ; //!! the Arrays seem to have a format where the first entry always contains the data and so forth...
                /* ... */
      
                // then do something with the data bits
      
           }
      

      【讨论】:

        【解决方案5】:

        您的主要问题是根据 RFC 4627,您拉入的 JSON 格式不正确或无效。

        您可以做的是获取 JSON 数据的副本并使用此工具格式化它http://www.freeformatter.com/json-formatter.html

        当你有了格式化版本之后,你就可以使用 jQuery ajax 调用了

        $.ajax({
            url: "your-formatted.json",
            dataType: 'json',
        
            success: function (data) {
        
                for (var i = 0; i < data.ss.length; i++) {
                    document.write("Day: " + data.ss[i][0]);
                    document.write("<br/>");
                    document.write("Time: " + data.ss[i][1]);
                    document.write("<br/><br/>");
                }
            }
        });
        

        您实际上不应该在应用程序中使用 document.write。这只是为了显示数据。

        【讨论】:

          【解决方案6】:

          对于这个特定问题(来自 JSON 响应的数组中的空索引),我使用前瞻断言进行了正则表达式替换。考虑到该请求包含XMLHttpRequest

          request.responseText.replace(/,(?=,)/gm, ",\"\"")
          

          这会将,, 转换为,"",,并且在序列中有更多逗号的情况下也可以使用,因此,,, 变为,"","",。之后可以使用JSON.parse()

          【讨论】:

            【解决方案7】:

            这个畸形的JSON可以被dirty-json NPM包解析(我是作者)。

            您可以在此处测试解析器的演示:https://rmarcus.info/dirty-json

            解析器将原始问题中的 JSON 解释为等效于以下有效 JSON:

            {
                "ss": [
                    [
                        "Thu",
                        "7:00",
                        "Final",
                        "BAL",
                        "19",
                        "ATL",
                        "20",
                        "56808",
                        "PRE4",
                        "2015"
                    ],
                    [
                        "Thu",
                        "7:00",
                        "Final",
                        "NO",
                        "10",
                        "GB",
                        "38",
                        "56809",
                        "PRE4",
                        "2015"
                    ]
                ]
            }
            

            【讨论】:

              猜你喜欢
              • 2013-08-19
              • 2016-08-09
              • 2021-10-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-25
              相关资源
              最近更新 更多