2010-12-08 21 views
6

Je reçois une réponse du serveur où la clé n'est pas entre guillemets. En l'analysant à l'aide de l'analyseur JSON open source, j'obtiens l'erreur suivante.Analyse json, clé sans guillemets

-JSONValue a échoué. L'erreur est: Unrecognized personnage principal

& si j'ajoute des guillemets doubles (") à la clé manuellement, je reçois ce que je veux Que dois-je faire

Thanx beaucoup d'avance

.?.

EDIT: s'il vous plaît voir ce qui suit, si son correct

{ 

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

    ] 

} 
+4

Contrôlez-vous le service? Si la clé n'est pas entre guillemets, ce n'est pas JSON valide. Peut-être que vous devriez aviser le propriétaire du service ... –

+1

+1 sur Felix Kling. JSON non valide, paire clé/valeur non valide NSDictionary. Le serveur devrait être réparé. – jv42

+0

J'ai posté la réponse. plz voir si c'est correct. En outre, le même travail avec la clé dans les guillemets doubles – sole007

Répondre

3

Je l'ai d'abord mis comme un commentaire, mais je pense que cela compte comme une réponse, mais pas nécessairement très utile.

L'exemple que vous avez publié est et non JSON. Vérifiez le JSON syntax. Les seules entités non cotées autorisées à l'exception des nombres, des objets et des tableaux sont null, true, false. Les clés de votre exemple sont donc invalides, de même que les valeurs non numériques. Donc, vous devriez vraiment signaler un problème au fournisseur de services (s'ils prétendent qu'ils produisent du JSON plutôt qu'une version modifiée). Si elles refusent de résoudre le problème, vous devrez écrire un analyseur presque-JSON ou en trouver un qui soit moins strict sur la syntaxe.

+0

ce n'est pas exactement la réponse du serveur, c'est juste le format. En outre, j'ai supprimé par erreur les doubles guillemets de la valeur. Ensuite, il fera le bon format, car je reçois la même erreur. – sole007

+1

@ sole007: Les clés sont toujours invalides. dans les clés JSON doivent être aussi des chaînes. – JeremyP

+0

voulez-vous dire entre guillemets? – sole007

0

Eh bien, vous auriez pour l'analyser manuellement pour être sûr d'obtenir les citations au bon endroit, mais si vous allez le faire, alors vous devriez simplement trier tout dans la structure appropriée pour commencer. L'alternative est de parler à quiconque exécute le serveur et de voir si vous pouvez les amener à produire du JSON à la place.

0

ce qui suit devrait être la réponse !!!

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 est un objet

+3

Ceci n'est pas différent de 'eval (object_str)', et il a tous les avantages et les inconvénients de 'eval'. Par exemple, quelqu'un pourrait inclure du code non-littéral dans l'objet, comme '" {un: 1, deux: 2, trois: function() {do_something_dangerous(); return 3;}()} "'. Vous obtiendrez un objet de '{one: 1, two: 2, three: 3}' mais celui qui vous a envoyé cette chaîne vous a juste demandé d'exécuter du code pour lui. –

1

Je voulais l'équivalent de ast.literal_eval de Python pour Javascript --- quelque chose qui n'analyser des objets littéraux comme JSON, mais que les clés de Javascript pratiques non cotées. (Ceci est pour l'entrée de données humaine, la simplicité et la rigueur de JSON standard serait préférable pour l'envoi de données entre serveurs.)

C'est aussi ce que l'affiche originale voulait, donc je vais mettre ma solution ici. J'ai utilisé le Esprima library pour construire un arbre de syntaxe abstraite, puis je me suis converti l'arbre en objets, comme ceci:

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"); 
} 

Le "var dummy = " + est nécessaire pour que Esprima interprète un caractère { initial comme le début d'une expression d'objet, plutôt qu'un bloc de code.

À aucun moment, le object_str n'est directement évalué, vous ne pouvez donc pas vous faufiler dans un code malveillant.En outre, les utilisateurs peuvent inclure des commentaires dans le object_str.

Pour ce genre de problème, YAML mérite également d'être considéré. Cependant, je voulais une vraie syntaxe Javascript car j'intégrais cela avec d'autres objets de saisie de données au format Javascript (j'avais donc d'autres raisons d'inclure la bibliothèque Esprima).