validator tutorial sintaxis online formato ejemplos json standards

tutorial - ¿La sintaxis JSON permite duplicar claves en un objeto?



json validator (11)

¿Es este JSON válido?

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

http://jsonlint.com/ dice que sí.

http://www.json.org/ no dice nada sobre que esté prohibido.

Pero obviamente no tiene mucho sentido, ¿verdad? La mayoría de las implementaciones probablemente usan una tabla hash, por lo que está siendo anulada de todos modos.


DEBE ser único, no significa que DEBE ser único. Sin embargo, como se dijo, algunos analizadores fallarían y otros simplemente usarían el último valor analizado. Sin embargo, si la especificación fue limpiada un poco para permitir duplicados, entonces podría ver un uso donde puede tener un controlador de eventos que está transformando el JSON a HTML o algún otro formato ... en tales casos sería perfectamente válido para analizar el JSON y crear otro formato de documento ...

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

podría analizar fácilmente a html, por ejemplo

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

Puedo ver el razonamiento detrás de la pregunta, pero tal como está ... no confiaría en eso.


De acuerdo con RFC-7159, el estándar actual para JSON publicado por Internet Engineering Task Force (IETF), establece que "los nombres dentro de un objeto DEBEN ser únicos". Sin embargo, de acuerdo con RFC-2119 que define la terminología utilizada en los documentos IETF, la palabra "debería" en realidad significa "... puede haber razones válidas en circunstancias particulares para ignorar un elemento en particular, pero se deben comprender todas las implicaciones y pesó cuidadosamente antes de elegir un curso diferente ". Lo que esto significa esencialmente es que, aunque se recomiendan llaves únicas, no es obligatorio. Podemos tener claves duplicadas en un objeto JSON, y aún sería válido.

De la aplicación práctica, he visto que el valor de la última clave se considera cuando se encuentran claves duplicadas en un JSON.


Del estándar (p. Ii) :

Se espera que otros estándares se refieran a este, que se adhiere estrictamente al formato de texto JSON, al tiempo que impone restricciones en varios detalles de codificación. Tales estándares pueden requerir comportamientos específicos. JSON en sí mismo no especifica ningún comportamiento.

Más abajo en el estándar (p.2), la especificación para un objeto JSON:

Una estructura de objeto se representa como un par de tokens de corchetes que rodean cero o más pares de nombre / valor. Un nombre es una cadena. Un token de dos puntos sigue a cada nombre, separando el nombre del valor. Un token de coma único separa un valor de un nombre siguiente.

No hace ninguna mención de que las claves duplicadas sean inválidas o válidas, por lo que de acuerdo con la especificación, supongo que eso significa que están permitidas.

Que la mayoría de las implementaciones de las bibliotecas JSON no acepten claves duplicadas no entra en conflicto con el estándar, debido a la primera cita.

Aquí hay dos ejemplos relacionados con la biblioteca estándar de C ++. Al deserializar un objeto JSON en un std::map , tendría sentido rechazar las claves duplicadas. Pero cuando se deserializa un objeto JSON en std::multimap , tendría sentido aceptar claves duplicadas de forma normal.


El estándar dice esto:

Los lenguajes de programación varían ampliamente según si admiten objetos, y si es así, qué características y restricciones ofrecen los objetos. Los modelos de sistemas de objetos pueden ser muy divergentes y continúan evolucionando. En cambio, JSON proporciona una notación simple para expresar colecciones de pares de nombre / valor. La mayoría de los lenguajes de programación tendrán alguna función para representar tales colecciones, que pueden ir por nombres como registro, estructura, dict, mapa, hash u objeto.

El error está en node.js al menos. Este código tiene éxito en node.js.

try { var json = {"name":"n","name":"v"}; console.log(json); // outputs { name: ''v'' } } catch (e) { console.log(e); }


En C # si deserializa un Dictionary<string, string> toma el último par de valor clave:

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

si intentas deserializar a

class Foo { [JsonProperty("a")] public string Bar { get; set; } [JsonProperty("a")] public string Baz { get; set; } } var f = JsonConvert.DeserializeObject<Foo>(json);

obtienes una excepción Newtonsoft.Json.JsonSerializationException .


Hay 2 documentos que especifican el formato JSON:

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

La respuesta aceptada cita del primer documento. Creo que el primer documento es más claro, pero el segundo contiene más detalles.

El segundo documento dice:

  1. Objetos

    Una estructura de objeto se representa como un par de llaves que rodean cero o más pares de nombre / valor (o miembros). Un nombre es una cadena. Un solo punto aparece después de cada nombre, separando el nombre del valor. Una coma individual separa un valor de un nombre siguiente. Los nombres dentro de un objeto DEBERÍAN ser únicos.

Por lo tanto, no está prohibido tener un nombre duplicado, pero se desaconseja.


La especificación JSON dice esto:

Un objeto es un conjunto desordenado de pares de nombre / valor.

La parte importante aquí es "desordenada": implica la unicidad de las claves, porque lo único que puede usar para referirse a un par específico es su clave.

Además, la mayoría de las librerías JSON deserializarán objetos JSON a hash maps / dictionaries, donde las claves están garantizadas únicas. Lo que sucede cuando deserializa un objeto JSON con claves duplicadas depende de la biblioteca: en la mayoría de los casos, obtendrá un error o solo se tendrá en cuenta el último valor para cada clave duplicada.

Por ejemplo, en Python, json.loads(''{"a": 1, "a": 2}'') devuelve {"a": 2} .


Me encontré con una pregunta similar cuando se trata de una API que acepta tanto XML como JSON, pero no documenta cómo se manejaría lo que se esperaría que fueran claves duplicadas en el JSON aceptado.

La siguiente es una representación XML válida de su muestra JSON:

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

Cuando esto se convierte en JSON, obtienes lo siguiente:

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

Un mapeo natural de un lenguaje que maneja lo que podría llamarse claves duplicadas para otro, puede servir como una posible referencia de mejores prácticas aquí.

Espero que ayude a alguien!


No está definido en el estándar ECMA JSON . Y en términos generales, la falta de definición en un estándar significa, "No cuente con que esto funcione de la misma manera en todas partes".

Si eres un jugador, "muchos" motores JSON permitirán la duplicación y simplemente usarán el último valor especificado. Esta:

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

Se convierte en esto:

Object {a: 3, b: 2}

¡Pero si no eres un jugador, no cuentes con eso!


Preguntando por propósito, hay diferentes respuestas:

Al usar JSON para serializar objetos (JavaScriptObjectNotation), cada elemento de diccionario se correlaciona con una propiedad de objeto individual, por lo que las diferentes entradas que definen un valor para la misma propiedad no tienen ningún significado.

Sin embargo, me encontré con la misma pregunta de un caso de uso muy específico: al escribir muestras de JSON para las pruebas de API, me preguntaba cómo agregar comentarios en nuestro archivo JSON sin romper la usabilidad. La especificación JSON no conoce los comentarios, así que se me ocurrió un enfoque muy simple:

Para usar claves duplicadas para comentar nuestras muestras JSON . Ejemplo:

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

Los serializadores JSON que estamos utilizando no tienen problemas con estos duplicados "OBSERVACIONES" y nuestro código de aplicación simplemente ignora esta pequeña sobrecarga.

Entonces, a pesar de que no hay ningún significado en la capa de aplicación, estos duplicados para nosotros proporcionan una valiosa solución para agregar comentarios a nuestras muestras de prueba sin romper la usabilidad de JSON.


La respuesta corta: Sí, pero no es recomendable.
La respuesta larga: depende de lo que llames válido ...


El formato de intercambio de datos JSON (ECMA-404) no dice nada sobre los nombres duplicados (claves).

Sin embargo, el Formato de intercambio de datos de JavaScript Object Notation (JSON) (RFC7159) dice:

Los nombres dentro de un objeto DEBERÍAN ser únicos.

En este contexto , debe entenderse como se especifica en RFC 2119

DEBERÍA Esta palabra, o el adjetivo "RECOMENDADO", significa que puede haber razones válidas en circunstancias particulares para ignorar un artículo en particular, pero las implicaciones completas deben ser entendidas y sopesadas cuidadosamente antes de elegir un curso diferente.



RFC 7159 explica por qué los nombres únicos (claves) son buenos:

Un objeto cuyos nombres son todos únicos es interoperable en el sentido
que todas las implementaciones de software que reciben ese objeto acordarán las asignaciones de nombre-valor. Cuando los nombres dentro de un objeto no son
único, el comportamiento del software que recibe dicho objeto es
impredecible. Muchas implementaciones informan el último par nombre / valor
solamente. Otras implementaciones informan un error o no pueden analizar el
objeto, y algunas implementaciones informan todos los pares nombre / valor,
incluyendo duplicados.

Se ha observado que las bibliotecas de análisis JSON difieren en si hacen que el pedido de los miembros del objeto sea visible para el software que realiza la llamada. Implementaciones cuyo comportamiento no depende del miembro
el pedido será interoperable en el sentido de que no serán
afectado por estas diferencias.



Tratar de analizar una cadena con nombres duplicados con la implementación de Java por Douglas Crockford (el creador de JSON) da como resultado una excepción:

org.json.JSONException: Duplicate key "status" at org.json.JSONObject.putOnce(JSONObject.java:1076)