使用Javascript解析格式错误的JSON

时间:2011-07-31 01:13:25

标签: javascript json parsing

我想使用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的东西。

这可能吗?任何好的教程开始?甚至一些起始代码?

7 个答案:

答案 0 :(得分:7)

一般来说,您可以使用JSON.parse来执行此操作。但是,您拥有的代码段似乎不是严格有效的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攻击开放里面的代码。

答案 1 :(得分:3)

我处于类似的位置 - 非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数据。以下示例说明了问题:

  

[ “太阳”, “4:25”, “最终” ,, “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;

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

答案 2 :(得分:0)

我们正在使用mootools这样的内容,但您也可以使用纯JavaScript:http://www.json.org/js.html

答案 3 :(得分:0)

根据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。这仅用于显示数据的目的。

答案 4 :(得分:0)

假设您已经有一个有效的JSON StringjsonString)来解析。 (如果您不知道如何从给定的网址中使用String检索要解析的XMLHttpRequest,则必须首先查看该内容。)


使用纯JavaScript,您将不得不添加Douglas Crockford的JSON库(或类似的东西),以便在没有本机实现的情况下提供解析Function

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 :(得分:0)

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

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

这会将,,变为,"",,如果序列中有更多逗号,也会有效,因此,,,变为,"","",。您可以在之后使用JSON.parse()

答案 6 :(得分:0)

这个格式错误的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"
        ]
    ]
}