La syntaxe JSON autorise-t-elle les clés dupliquées dans un objet?

est-ce valide json?

{
    "a" : "x",
    "a" : "y"
}

http://jsonlint.com dit oui.

http://www.json.org / ne dit pas que c'est interdit.

mais évidemment ça n'a pas beaucoup de sens, n'est-ce pas? La plupart des implémentations utilisent probablement un hashtable de sorte qu'il est de toute façon annulé.

135
demandé sur clamp 2014-02-17 19:16:02

11 réponses

à Partir de le standard (p. ii) :

on s'attend à ce que d'autres normes fassent référence à celle-ci, en respectant strictement le format de texte JSON, tandis que imposition de restrictions sur divers détails d'encodage. De telles normes peuvent exiger des comportements spécifiques. JSON elle-même ne spécifie aucun comportement.

plus bas dans la norme (p. 2), la spécification pour un objet JSON:

une structure d'objet est représentée sous la forme d'une paire de jetons à crochet Bouclé entourant des paires zéro ou plus de nom/valeur. Un nom est une chaîne de caractères. Un seul jeton de deux points suit chaque nom, séparant le nom de la valeur. Single la virgule sépare une valeur d'un nom suivant.

Diagram for JSON Object

il ne fait aucune mention de clés dupliquées étant invalides ou valides, de sorte que selon le spécification je présumer que signifie qu'ils sont autorisés.

que la plupart des implémentations des bibliothèques JSON ne pas acceptent les clés en double n'est pas en conflit avec la norme, en raison de la première citation.

voici deux exemples relatifs à la bibliothèque standard C++. Lors de la desérialisation d'un objet JSON dans un std::map , il serait logique de refuser les clés dupliquées. Mais lors de la desérialisation d'un objet JSON std::multimap il serait logique d'accepter les clés dupliquées comme normales.

84
répondu Timothy Shields 2014-02-17 16:10:16

La réponse courte: Oui, mais n'est pas recommandée.

La longue réponse: Cela dépend de ce que vous appelez valide...



Le JSON Data Interchange Format (ECMA-404) ne dit rien au sujet des noms (clés) dupliqués.

Toutefois, JavaScript Object Notation (JSON) d'Échange de Données Format) (RFC7159) says:

les noms d'un objet doivent être uniques.

dans ce contexte si doit être compris comme spécifié dans RFC 2119 "1519130920

si ce mot, ou l'adjectif "recommandé", signifie qu'il peut exister des raisons valides dans des circonstances particulières d'ignorer un particulier item, mais toutes les implications doivent être comprises et soigneusement pesé avant de choisir un cours différent.





RFC 7159 explique pourquoi les noms uniques (clés) sont bons:

un objet dont les noms sont tous uniques est interopérable dans le sens

que toutes les implémentations logicielles recevant cet objet seront d'accord sur le nom de la valeur des mappages. Lorsque les noms dans un objet ne sont pas

unique, le comportement du logiciel qui reçoit un tel objet est

imprévisible. De nombreuses implémentations rapportent la paire nom/valeur

seulement. D'autres implémentations signalent une erreur ou ne parviennent pas à analyser le

objet, et certaines implémentations reportent toutes les paires nom / valeur,

y compris les doublons.

JSON bibliothèques d'analyse ont été observés diffèrent quant à savoir si ils fassent ou non l'ordre des membres de l'objet visible à l'appel logiciel. Implémentations dont le comportement ne dépend pas du membre

la commande sera interopérable en ce sens qu'elle ne sera pas

touchés par ces différences.






En outre, comme Serguei l'a souligné dans les commentaires:
ECMA-262 " Spécification du langage ECMAScript®", se lit:

dans le cas où il y a des chaînes de noms dupliquées dans un objet, les valeurs lexicalement précédentes de la même clé doivent être écrasées.

(en d'autres termes la dernière valeur qui gagne).






essayer d'analyser une chaîne avec des noms dupliqués avec la Java implementation par Douglas Crockford (le créateur de JSON) se traduit par une exception:

org.json.JSONException: Duplicate key "status"  at
org.json.JSONObject.putOnce(JSONObject.java:1076)
90
répondu user454322 2018-07-23 02:37:48

il y a 2 documents spécifiant le format JSON:

  1. http://json.org /
  2. https://tools.ietf.org/html/rfc7159

la réponse acceptée est tirée du premier document. Je pense que le premier document est plus clair, mais le second contient plus de détails.

le 2ème document dit:

  1. objets

    une structure d'objet est représentée par une paire de crochets bouclés autour de zéro ou plus de paires nom / valeur (ou membres). Un nom est une chaîne. Un seul côlon vient après chaque nom, séparant le nom à partir de la valeur. Une seule virgule sépare une valeur d'une suivante nom. les noms d'un objet doivent être uniques.

donc c'est pas interdit d'avoir un nom en double, mais il est découragé.

14
répondu toongeorges 2016-07-08 13:07:29

j'ai rencontré une question similaire en traitant avec une API qui accepte à la fois XML et JSON, mais ne documente pas comment il traiterait ce que vous attendez d'être des clés dupliquées dans le JSON accepté.

ce qui suit est une représentation XML valide de votre JSON échantillon:

<object>
  <a>x</a>
  <a>y</a>
</object>

quand ceci est converti en JSON, vous obtenez ce qui suit:

{
  "object": {
    "a": [
      "x",
      "y"
    ]
  }
}

une cartographie naturelle à partir d'un langage qui gère ce que vous pourrait appeler des clés dupliquées à une autre, peut servir de référence de meilleure pratique potentielle ici.

Espère que ça aide quelqu'un!

8
répondu a darren 2016-01-19 11:22:40

La spécification JSON dit ceci:

un objet est un ensemble non ordonné de paires nom/valeur.

la partie importante ici est" unordered": elle implique l'unicité des clés, parce que la seule chose que vous pouvez utiliser pour se référer à une paire spécifique est sa clé.

de plus, la plupart des libs de JSON vont desérialiser les objets JSON pour les cartes de hachage/dictionnaires, où les clés sont garanties uniques. Ce qui se passe quand vous la desérialisation d'un objet JSON avec des clés dupliquées dépend de la bibliothèque: dans la plupart des cas, vous obtiendrez une erreur, ou seulement la dernière valeur pour chaque clé dupliquée sera prise en compte.

par exemple, en Python, json.loads('{"a": 1, "a": 2}') retourne {"a": 2} .

6
répondu Max Noel 2014-02-17 15:32:19

demandant pour but, il y a différentes réponses:

utilisant JSON pour sérialiser des objets (JavaScriptObjectNotation), chaque élément du dictionnaire correspond à une propriété d'objet individuelle, de sorte que différentes entrées définissant une valeur pour la même propriété n'a pas de sens.

cependant, je suis venu sur la même question d'un cas d'utilisation très spécifique: Ecrire Des échantillons JSON pour les tests API, je me demandais comment ajouter des commentaires dans notre fichier JSON convivialité. Le JSON spec ne connaît pas les commentaires, donc j'ai trouvé une approche très simple:

pour utiliser des clés en double pour commenter nos échantillons JSON . Exemple:

{ "property1" : "value1", "REMARK" : "... prop1 controls ...", "property2" : "value2", "REMARK" : "... value2 raises an exception ...", }

les sérialiseurs JSON que nous utilisons n'ont aucun problème avec ces duplicata" REMARK " et notre code d'application ignore tout simplement ce petit overhead.

ainsi, bien qu'il n'y ait aucun sens sur le application layer, ces duplicata pour nous fournissent une solution de rechange valable pour ajouter des commentaires à nos échantillons de test sans briser la convivialité du JSON.

2
répondu aknoepfel 2015-09-02 17:13:09

doit être unique ne signifie pas doit être unique. Cependant, comme indiqué, certains analyseurs échoueraient et d'autres utiliseraient simplement la dernière valeur analysée. Cependant, si la spécification a été un peu nettoyée pour permettre les doublons, alors je pourrais voir une utilisation où vous pourriez avoir un gestionnaire d'événements qui transforme le JSON en HTML ou un autre format...dans de tels cas, il serait parfaitement valide de parser le JSON et de créer un autre format de document...

[
  "div":
  {
    "p":"hello",
    "p":"universe"
  }
  "div":
  {
    "h1":"Heading 1",
    "p":"another paragraph"
  }
]

pourrait alors facilement parse au html par exemple

<body>
 <div>
  <p>hello</p>
  <p>universe</p>
 </div>
 <div>
  <h1>Heading 1</h1>
  <p>another paragraph</p>
 </div>
</body>

je peux voir le raisonnement derrière la question mais telle qu'elle se présente...Je n'aurais pas confiance en elle.

2
répondu Colin Saxton 2016-10-14 17:06:34

il n'est pas défini dans la norme ECMA JSON . Et d'une manière générale, un manque de définition dans une norme signifie, "Ne comptez pas sur le fait que cela fonctionne de la même manière partout."

si vous êtes un joueur," beaucoup " de moteurs JSON permettront la duplication et utiliseront simplement la dernière valeur spécifiée. Ceci:

var o = {"a": 1, "b": 2, "a": 3}

devient ceci:

Object {a: 3, b: 2}

mais si vous n'êtes pas Joueur, ne comptez pas sur c'!

1
répondu svidgen 2014-02-17 15:38:36

Conformément à la norme RFC-7159, la norme actuelle pour le JSON publié par l'Internet Engineering Task Force (IETF), les états "Les noms à l'intérieur d'un objet DOIT être unique". Toutefois, selon la RFC-2119 qui définit la terminologie utilisée dans les documents de l'IETF, le mot "devrait" signifie en fait "... il peut y avoir des raisons valables, dans des circonstances particulières, de ne pas tenir compte d'un élément particulier, mais il faut en comprendre toutes les implications et les peser soigneusement avant de choisir une autre voie." Quel cela signifie essentiellement que tout en ayant des Clés uniques est recommandé, il n'est pas un must. Nous pouvons avoir des clés dupliquées dans un objet JSON, et cela serait toujours valide.

de l'application pratique, j'ai vu la valeur de la dernière clé est considérée quand les clés dupliquées sont trouvées dans un JSON.

1
répondu Navaneetha 2017-07-11 02:47:34

en C# si vous desérialisez à un Dictionary<string, string> il prend la dernière paire de valeur clé:

string json = @"{""a"": ""x"", ""a"": ""y""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
// { "a" : "y" }

si vous essayez de desérialiser en

class Foo
{
    [JsonProperty("a")]
    public string Bar { get; set; }

    [JsonProperty("a")]
    public string Baz { get; set; }
}

var f = JsonConvert.DeserializeObject<Foo>(json);

vous obtenez une exception Newtonsoft.Json.JsonSerializationException .

0
répondu Sam Leach 2014-02-17 15:43:43

la norme dit ceci:

les langages de programmation varient grandement quant à la prise en charge des objets, et dans l'affirmative, quelles sont les caractéristiques et les contraintes des objets? Le les modèles de systèmes d'objets peuvent être très divergentes, et continuent à évoluer. JSON fournit à la place une notation simple pour exprimer les collections de paires nom/valeur. La plupart des langages de programmation aura certaines fonctionnalités pour représenter de telles collections, qui peuvent aller par noms comme enregistrer, struct, dict, carte, hachage ou d'un objet.

le bug est dans le noeud.js au moins. Ce code succède à node.js.

try {
     var json = {"name":"n","name":"v"};
     console.log(json); // outputs { name: 'v' }
} catch (e) {
     console.log(e);
}
0
répondu John Carlson 2015-02-21 01:39:41