¿Cuál es el JSON mínimo válido?

175

He leído cuidadosamente la descripción de JSON http://json.org/ pero no estoy seguro de saber la respuesta a la simple pregunta. ¿Qué cadenas son el mínimo posible JSON válido?

  • "string" ¿es válida la cadena JSON?
  • 42 ¿Es el número simple válido JSON?
  • true ¿Es el valor booleano un JSON válido?
  • {} ¿Es el objeto vacío un JSON válido?
  • [] ¿Es la matriz vacía un JSON válido?
bessarabov
fuente
12
Probando en jsonlint.com , los dos últimos son válidos, los otros no.
ironcito
1
algunos analizadores JSON esperan una matriz o un objeto. Se quejan de solo un número o una cadena.
akonsu
3
A partir de ahora, los que son válidos
Brian Colavito
respuesta corta - {}
Tukaram Bhosale

Respuestas:

157

Al momento de escribir, JSON se describió únicamente en RFC4627 . Describe (al comienzo de "2") un texto JSON como un objeto o conjunto serializado.

Esto significa que solo {} y []son válidas, completar cadenas JSON en analizadores y stringifiers que cumplan con ese estándar.

Sin embargo , la introducción de ECMA-404 cambia eso, y el consejo actualizado se puede leer aquí . También he escrito una publicación de blog sobre el tema.


Sin embargo, para confundir aún más el asunto, el JSONobjeto (por ejemplo, JSON.parse()y JSON.stringify()) disponible en los navegadores web está estandarizado en ES5 , y eso define claramente los textos JSON aceptables de esta manera:

El formato de intercambio JSON utilizado en esta especificación es exactamente el descrito por RFC 4627 con dos excepciones:

  • La producción JSONText de nivel superior de la gramática JSON ECMAScript puede consistir en cualquier valor JSON en lugar de estar restringido a ser un objeto JSON o un JSONArray según lo especificado por RFC 4627.

  • recortado

Esto significaría que el objeto JSON acepta todos los valores JSON (incluidas las cadenas, los valores nulos y los números), aunque el objeto JSON se adhiera técnicamente a RFC 4627.

Tenga en cuenta que, por lo tanto, podría encadenar un número en un navegador conforme a través de JSON.stringify(5), que sería rechazado por otro analizador que se adhiera a RFC4627, pero que no tenga la excepción específica mencionada anteriormente. Ruby, por ejemplo, parece ser uno de esos ejemplos que solo acepta objetos y matrices como raíz . PHP, por otro lado, agrega específicamente la excepción de que "también codificará y decodificará tipos escalares y NULL".

Mate
fuente
@amdorra: ¿Puedes ser más específico donde estás viendo eso?
Matt
55
JSON no es un sustantivo, por lo que "un JSON" no tiene sentido. Cualquier "valor JSON" es un "valor JSON", pero los analizadores a menudo esperan un "texto JSON" como se define en ese RFC.
IMSoP
2
mi mal
borraré
1
@ jmoreno ¿Podría por favor aclarar su comentario? ¿Estás diciendo true, falseo nullsolo es un texto JSON válido? ¿Podría por favor citar una fuente, ya que esto contradice la mayoría de las otras respuestas / comentarios aquí?
Lawrence Johnston el
2
@ jmoreno: Seguramente la cita de la sección 2 "Un texto JSON es un objeto o conjunto serializado". ¿Se opone a eso? JSON Lint tampoco cree que una no matriz u objeto sea válido. No hay debate sobre si una cadena es un literal JSON válido; esto termina si una cadena por sí misma es válida.
Matt
42

Hay al menos cuatro documentos que pueden considerarse estándares JSON en Internet. Todos los RFC a los que se hace referencia describen el tipo mime application/json. Esto es lo que cada uno tiene que decir sobre los valores de nivel superior, y si se permite algo más que un objeto o una matriz en la parte superior:

RFC-4627 : No.

Un texto JSON es una secuencia de tokens. El conjunto de tokens incluye seis caracteres estructurales, cadenas, números y tres nombres literales.

Un texto JSON es un objeto o conjunto serializado.

Texto JSON = objeto / matriz

Tenga en cuenta que RFC-4627 fue marcado como "informativo" en lugar de "estándar propuesto", y que está obsoleto por RFC-7159 , que a su vez está obsoleto por RFC-8259.

RFC-8259 : sí.

Un texto JSON es una secuencia de tokens. El conjunto de tokens incluye seis caracteres estructurales, cadenas, números y tres nombres literales.

Un texto JSON es un valor serializado. Tenga en cuenta que ciertas especificaciones anteriores de JSON restringieron un texto JSON para ser un objeto o una matriz. Las implementaciones que generan solo objetos o matrices donde se requiere un texto JSON serán interoperables en el sentido de que todas las implementaciones aceptarán estos como textos JSON conformes.

Texto JSON = valor ws ws

RFC-8259 está fechado en diciembre de 2017 y está marcado como "ESTÁNDAR DE INTERNET".

ECMA-262 : Sí.

La gramática sintáctica JSON define un texto JSON válido en términos de tokens definidos por la gramática léxica JSON. El símbolo del objetivo de la gramática es JSONText.

Sintaxis JSONText:

JSONValue

Valor JSON:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : sí.

Un texto JSON es una secuencia de tokens formados a partir de puntos de código Unicode que se ajustan a la gramática del valor JSON. El conjunto de tokens incluye seis tokens estructurales, cadenas, números y tres tokens de nombre literal.

Johann
fuente
10

De acuerdo con la definición anterior en RFC 4627 (que fue obsoleta en marzo de 2014 por RFC 7159), esos eran todos "valores JSON" válidos, pero solo los dos últimos constituirían un "texto JSON" completo:

Un texto JSON es un objeto o conjunto serializado.

Dependiendo del analizador utilizado, los "valores JSON" solitarios pueden ser aceptados de todos modos. Por ejemplo (apegarse a la terminología de "valor JSON" frente a "texto JSON"):

  • la JSON.parse()función ahora estandarizada en los navegadores modernos acepta cualquier "valor JSON"
  • la función PHP json_decodese introdujo en la versión 5.2.0 solo aceptando un "texto JSON" completo, pero se modificó para aceptar cualquier "valor JSON" en la versión 5.2.1
  • Python json.loadsacepta cualquier "valor JSON" de acuerdo con los ejemplos en esta página del manual
  • el validador en http://jsonlint.com espera un "texto JSON" completo
  • el módulo Ruby JSON solo aceptará un "texto JSON" completo (al menos según los comentarios en esta página del manual )

La distinción es un poco como la distinción entre un "documento XML" y un "fragmento XML", aunque técnicamente <foo />es un documento XML bien formado (sería mejor escribirlo <?xml version="1.0" ?><foo />, pero como se señala en los comentarios, la <?xmldeclaración es técnicamente opcional )

IMSoP
fuente
La comparación XML puede ser inapropiada, porque un documento XML es completamente válido sin la declaración XML opcional. Vea la recomendación XML en w3.org/TR/xml/#sec-well-formed
Gunther
@Gunther Ah, sí, me había olvidado de que es técnicamente opcional, aunque muy recomendable.
IMSoP
@Gunther: Un nitpick: <foo />es un documento XML bien formado , pero no válido . (Pero lo mismo es cierto para <?xml version="1.0" ?><foo />.)
ruakh
@ruakh Curiosamente, la definición aquí implica que XML solo puede ser "válido" frente a un DTD, lo que significa que muy pocos documentos XML lo son, ya que los DTD rara vez se escriben y declaran en la práctica (en comparación con los formatos de definición de esquema como XSD o RelaxNG) . Estaba comprobando, porque si pudieras ser válido contra un esquema externo, sin hacer referencia a él, entonces <foo /> puede o no ser válido contra un esquema particular , pero eso no es lo que ese estándar establece.
IMSoP
4

La especificación ecma podría ser útil como referencia:

http://www.ecma-international.org/ecma-262/5.1/

La función de análisis analiza un texto JSON (una cadena con formato JSON) y produce un valor ECMAScript. El formato JSON es una forma restringida de literal ECMAScript. Los objetos JSON se realizan como objetos ECMAScript. Las matrices JSON se realizan como matrices ECMAScript. Las cadenas JSON, números, booleanos y nulos se realizan como cadenas ECMAScript, números, booleanos y nulos. JSON utiliza un conjunto de caracteres de espacio en blanco más limitado que WhiteSpace y permite que los puntos de código Unicode U + 2028 y U + 2029 aparezcan directamente en literales JSONString sin usar una secuencia de escape. El proceso de análisis es similar a 11.1.4 y 11.1.5 como lo limita la gramática JSON.

JSON.parse("string"); // SyntaxError: Unexpected token s
JSON.parse(43); // 43
JSON.parse("43"); // 43
JSON.parse(true); // true
JSON.parse("true"); // true
JSON.parse(false);
JSON.parse("false");
JSON.parse("trueee"); // SyntaxError: Unexpected token e
JSON.parse("{}"); // {}
JSON.parse("[]"); // []
Emil A.
fuente
44
Si bien es una referencia útil, esa es la especificación de un analizador JSON particular (el definido en el estándar ECMAScript) no para el formato en sí. json.org declara explícitamente que JSON es "completamente independiente del lenguaje", por lo que no hay un analizador correcto.
IMSoP
1
JavaScript / ECMAScipt es la inspiración para JSON y un usuario de él, pero no el "hogar" del mismo. JSON se derivó de la notación literal del objeto en (todas las versiones anteriores de) ECMAScript, pero no es idéntico a él. La JSON.parsefunción se agregó luego a versiones posteriores del estándar ECMAScript basado en la gramática de Crockford y el RFC.
IMSoP
44
Deberías hacerloJSON.parse("\"string\"");
ericbn
4

JSON significa JavaScript Object Notation. Solo {}y []define un objeto Javascript. Los otros ejemplos son valores literales. Hay tipos de objetos en Javascript para trabajar con esos valores, pero la expresión "string"es una representación del código fuente de un valor literal y no un objeto.

Tenga en cuenta que JSON no es Javascript. Es una notación que representa datos. Tiene una estructura muy simple y limitada. Los datos JSON se estructuran con {},:[]caracteres. Solo puede usar valores literales dentro de esa estructura.

Es perfectamente válido que un servidor responda con una descripción de objeto o un valor literal. Todos los analizadores JSON deben manejarse para manejar solo un valor literal, pero solo un valor. JSON solo puede representar un solo objeto a la vez. Entonces, para que un servidor devuelva más de un valor, debería estructurarlo como un objeto o una matriz.

Reactgular
fuente
1
Creo que abordar la respuesta desde esta dirección confunde más de lo que aclara: el origen del nombre no tiene relación con los detalles del estándar, y los tipos disponibles en JavaScript pueden ser una inspiración para los tipos en JSON, pero no hay ningún requisito que coinciden La introducción en json.org deja esto claro: "JSON es un formato de texto que es completamente independiente del idioma"
IMSoP
@IMSoP Estoy totalmente de acuerdo. Mezclé tipos de Javascript con JSON y eso no es correcto. Actualizaré mi respuesta.
Reactgular
2

Si si SI SI y si. Todos ellos son literales de valor JSON válidos.

Sin embargo, el RFC 4627 oficial establece:

Un texto JSON es un objeto o conjunto serializado.

Por lo tanto, un "archivo" completo debe consistir en un objeto o matriz como la estructura más externa, que por supuesto puede estar vacía. Sin embargo, muchos analizadores JSON aceptan valores primitivos también para la entrada.

Bergi
fuente
-1
var x;
JSON.stringify(x); // will output "{}"

Entonces su respuesta es la "{}"que denota un objeto vacío.

Jani Hyytiäinen
fuente
FWIW, en Chrome, esto da undefined, no "{}" `
Matt
-2

Simplemente siga los diagramas ferroviarios que figuran en la página json.org . [] y {} son los objetos JSON válidos mínimos posibles. Entonces la respuesta es [] y {}.

Hrishi
fuente
3
No es un FSM, es una gramática. Y no parece indicar qué producción es la regla de inicio. Si las reglas de inicio fueran arrayy objectestaría en lo cierto, pero es razonable esperar valueque sea el comienzo.
Sin embargo, me parece bastante sencillo. Douglas Crockford los llama así y siempre comenzamos desde la izquierda y seguimos las pistas hacia la derecha. La pista más pequeña proporciona el JSON mínimo válido.
Hrishi
2
No es su interpretación de ninguna regla gramatical en particular a lo que me opongo, es que elige dos reglas y asume que una solo puede comenzar a partir de ellas, no de otras. Si observa la valuesregla en su lugar (o además de) las reglas arrayy object, los números y las cadenas independientes son un documento JSON válido.
-1. En primer lugar, como señala @delnan, nada en los diagramas de json.org sugiere que un texto JSON completo debe ser un objeto o matriz; has elegido esos dos arbitrariamente, no en base a nada en json.org. En segundo lugar, analizar minuciosamente la terminología: []si bien un texto JSON válido según cada especificación que haya tenido una opinión al respecto, no es un "objeto JSON válido", ya que no es un objeto JSON. "Objeto" en JSON se refiere específicamente a la {}notación; Las matrices JSON no son objetos JSON.
Mark Amery