2010-12-08 172 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庫)。