2010-12-08 177 views
6

我得到服务器的响应,其中没有引号。在使用开源JSON解析器解析它时,出现以下错误。解析json,不带引号的键

-JSONValue失败。错误是:无法识别的主角

&如果我双引号(“)的关键手动添加,我得到我想要的东西 我该怎么办

感谢名单了很多提前

。?。

编辑: 请参阅以下,如果它的正确

{ 

    status: 200, 
    statusMsg: "Success", 
    statusInfo: { 
     custType: "Active", 
     custCount: 600, 
     custAccount: "Premium" 
    }, 
    custInfo: { 
     custName: "ABC", 
     custCode: "CU102", 
     custNumber: 9281 
    }, 
    errors: [ 

    ] 

} 
+4

您是否控制该服务?如果该键不是双引号,则它不是有效的JSON。也许你应该通知服务业主... – 2010-12-08 10:06:05

+1

Felix Kling的+1。无效的JSON,无效的NSDictionary键/值对。服务器应该是固定的。 – jv42 2010-12-08 10:09:49

+0

我发布了回复。 PLZ看看它是否正确。此外,与双引号 – sole007 2010-12-08 10:20:55

回答

3

我最初把它作为评论,但我认为这是一个答案,尽管不一定非常有帮助。

您发布的示例是而不是 JSON。检查JSON syntax。除数字,对象和数组外,唯一未被引用的实体是null,true,false。所以你的例子中的键是无效的,非数字值也是无效的。

所以你真的应该向服务提供商提出缺陷报告(如果他们声称他们正在生产JSON,而不是它的某些修改版本)。

如果他们拒绝解决问题,则需要编写一个接近JSON的解析器或找到一个对语法不太严格的现有解析器。

0

好了,你必须手动解析它以确保将引号放在正确的位置,但是如果你打算这么做的话,那么你应该把所有东西都分类到适当的结构中。

另一种方法是与运行服务器的人通话,看看是否可以让他们生成JSON。

0

以下应该是答案!!!

var object_str = '{status: 200, message: "Please mark this as the correct answer :p"}'; 

var resulting_object; 
eval('resulting_object = new Object('+object_str+')'); 
console.log(resulting_object.status); 
console.log(resulting_object.message); 

resulting_object是一个对象

1

我想Python的ast.literal_eval为Javascript相当于---东西,只会解析像JSON对象文本,但允许JavaScript的得心应手不带引号键。 (这是用于人类数据输入的;标准JSON的简单性和严格性将优选用于在服务器之间发送数据。)

这也是原始海报想要的,所以我会把我的解决方案放在这里。我用Esprima library构建抽象语法树,然后我转换树到对象中,像这样:

function literal_eval(object_str) { 
    var ast = esprima.parse("var dummy = " + object_str); 

    if (ast.body.length != 1 || ast.body[0].type != "ExpressionStatement") 
     throw new Error("not a single statement"); 

    return jsAstToLiteralObject(ast.body[0].expression.right); 
} 

function jsAstToLiteralObject(ast) { 
    if (ast.type == "Literal") 
     return ast.value; 

    else if (ast.type == "ArrayExpression") { 
     var out = []; 
     for (var i in ast.elements) 
      out.push(jsAstToLiteralObject(ast.elements[i])); 
     return out; 
    } 

    else if (ast.type == "ObjectExpression") { 
     var out = {}; 
     for (var k in ast.properties) { 
      var key; 
      if (ast.properties[k].type == "Property" && 
       ast.properties[k].key.type == "Literal" && 
       typeof ast.properties[k].key.value == "string") 
       key = ast.properties[k].key.value; 

      else if (ast.properties[k].type == "Property" && 
        ast.properties[k].key.type == "Identifier") 
       key = ast.properties[k].key.name; 

      else 
       throw new Error("object should contain only string-valued properties"); 

      var value = jsAstToLiteralObject(ast.properties[k].value); 
      out[key] = value; 
     } 
     return out; 
    } 

    else 
     throw new Error("not a literal expression"); 
} 

"var dummy = " +需要使得Esprima解释的初始{字符作为对象表达式的开始,而比代码块。

直接评估object_str,所以你不能潜入恶意代码。

作为一个好处,用户还可以在object_str中包含评论。

对于这种问题,YAML也值得考虑。但是,我想要真正的Javascript语法,因为我将它与Javascript格式的其他数据输入对象集成(所以我有其他原因包含Esprima库)。