Qual é o JSON mínimo válido?

Li atentamente a descrição do JSON http://json.org/, mas não tenho certeza se conheço a resposta para a pergunta simples. Quais strings são o mínimo possível do JSON válido?

  • "string" é a string JSON válida?
  • 42 é o número simples válido JSON?
  • true é o valor booleano de um JSON válido?
  • {} o object vazio é um JSON válido?
  • [] o array vazio é um JSON válido?

No momento em que este artigo foi escrito, o JSON foi descrito apenas na RFC4627 . Ele descreve (no início de “2”) um texto JSON como sendo um object serializado ou matriz.

Isso significa que apenas {} e [] são válidas, seqüências de caracteres JSON completas em analisadores e sequenciadores que aderem a esse padrão.

No entanto , a introdução do ECMA-404 altera isso, e os conselhos atualizados podem ser lidos aqui . Eu também escrevi uma postagem no blog sobre o assunto.


Para confundir ainda mais o assunto, o object JSON (por exemplo, JSON.parse() e JSON.stringify() ) disponível nos navegadores da Web é padronizado no ES5 , e isso define claramente os textos JSON aceitáveis ​​da seguinte forma:

O formato de intercâmbio JSON usado nesta especificação é exatamente o descrito pela RFC 4627 com duas exceções:

  • A produção JSONText de nível superior da gramática ECMAScript JSON pode consistir em qualquer JSONValue em vez de estar restrita a ser um JSONObject ou um JSONArray, conforme especificado pela RFC 4627.

  • recortado

Isso significaria que todos os valores JSON (incluindo strings, nulos e números) são aceitos pelo object JSON, mesmo que o object JSON tecnicamente adira ao RFC 4627.

Observe que você pode, portanto, restringir um número em um navegador em conformidade via JSON.stringify(5) , que seria rejeitado por outro analisador que adere à RFC4627, mas que não possui a exceção específica listada acima. Ruby, por exemplo, parece ser um exemplo que aceita apenas objects e matrizes como a raiz . PHP, por outro lado, adiciona especificamente a exceção que “também codificará e decodificará tipos escalares e NULL”.

Existem pelo menos quatro documentos que podem ser considerados padrões JSON na Internet. Todos os RFCs referenciados descrevem o application/json tipo MIME. Aqui está o que cada um tem a dizer sobre os valores de nível superior e se algo diferente de um object ou matriz é permitido na parte superior:

RFC-4627 : Não.

Um texto JSON é uma sequência de tokens. O conjunto de tokens inclui seis caracteres estruturais, strings, números e três nomes literais.

Um texto JSON é um object serializado ou matriz.

JSON-text = object / array

Observe que o RFC-4627 foi marcado como “informativo”, em oposição ao “padrão proposto”, e que está obsoleto pelo RFC-7159 , que, por sua vez, é obsoleto pelo RFC-8259.

RFC-8259 : sim.

Um texto JSON é uma sequência de tokens. O conjunto de tokens inclui seis caracteres estruturais, strings, números e três nomes literais.

Um texto JSON é um valor serializado. Observe que determinadas especificações anteriores de JSON restringiram um texto JSON a ser um object ou uma matriz. Implementações que geram apenas objects ou matrizes para as quais um texto JSON é chamado serão interoperáveis ​​no sentido de que todas as implementações os aceitarão como textos JSON em conformidade.

JSON-text = ws valor ws

O RFC-8259 tem data de dezembro de 2017 e está marcado como “INTERNET STANDARD”.

ECMA-262 : Sim

A Gramática Sintática do JSON define um texto JSON válido em termos de tokens definidos pela gramática léxico JSON. O símbolo da meta da gramática é JSONText.

Sintaxe JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : sim.

Um texto JSON é uma sequência de tokens formados a partir de pontos de código Unicode que estão em conformidade com a gramática de valores JSON. O conjunto de tokens inclui seis tokens estruturais, strings, números e três tokens de nome literal.

De acordo com a antiga definição na RFC 4627 (que estava obsoleta em março de 2014 pela RFC 7159), todos eram “valores JSON” válidos, mas somente os dois últimos seriam um “texto JSON” completo:

Um texto JSON é um object serializado ou matriz.

Dependendo do analisador usado, os “valores JSON” solitários podem ser aceitos de qualquer maneira. Por exemplo (aderindo à terminologia “JSON value” vs “JSON text”):

  • a function JSON.parse() agora padronizada em navegadores modernos aceita qualquer “valor JSON”
  • A function PHP json_decode foi introduzida na versão 5.2.0 aceitando apenas um “texto JSON” inteiro, mas foi emendada para aceitar qualquer “valor JSON” na versão 5.2.1
  • O json.loads do Python aceita qualquer “valor JSON” de acordo com os exemplos nesta página de manual
  • o validador em http://jsonlint.com espera um “texto JSON” completo
  • o módulo Ruby JSON aceitará apenas um “texto JSON” completo (pelo menos de acordo com os comentários nesta página do manual )

A distinção é um pouco como a distinção entre um “documento XML” e um “fragment XML”, embora tecnicamente seja um documento XML bem formado (seria melhor escrito como , mas como apontado nos comentários, a declaração é tecnicamente opcional.

JSON significa JavaScript Object Notation. Somente {} e [] definem um object Javascript. Os outros exemplos são literais de valor. Existem tipos de object em Javascript para trabalhar com esses valores, mas a expressão "string" é uma representação do código fonte de um valor literal e não um object.

Tenha em mente que o JSON não é Javascript. É uma notação que representa dados. Tem uma estrutura muito simples e limitada. Os dados JSON são estruturados usando caracteres {},:[] . Você só pode usar valores literais dentro dessa estrutura.

É perfeitamente válido que um servidor responda com uma descrição de object ou um valor literal. Todos os analisadores JSON devem ser manipulados para manipular apenas um valor literal, mas apenas um valor. O JSON pode representar apenas um único object por vez. Portanto, para um servidor retornar mais de um valor, ele teria que estruturá-lo como um object ou uma matriz.

A especificação ecma pode ser útil para referência:

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

A function de análise analisa um texto JSON (uma String formatada em JSON) e produz um valor ECMAScript. O formato JSON é uma forma restrita do literal ECMAScript. Objetos JSON são percebidos como objects ECMAScript. Matrizes JSON são realizadas como matrizes ECMAScript. Cadeias JSON, números, booleanos e nulos são percebidos como Strings ECMAScript, Numbers, Booleans e null. O JSON usa um conjunto mais limitado de caracteres de espaço em branco do que o WhiteSpace e permite que os pontos de código Unicode U + 2028 e U + 2029 apareçam diretamente nos literais JSONString sem usar uma seqüência de escape. O processo de análise é semelhante ao 11.1.4 e 11.1.5, conforme restringido pela 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("[]"); // [] 

Sim, sim, sim, sim e sim. Todos eles são literais de valor JSON válidos.

No entanto, o RFC 4627 oficial afirma:

Um texto JSON é um object serializado ou matriz.

Portanto, um “arquivo” inteiro deve consistir em um object ou matriz como a estrutura mais externa, que, é claro, pode estar vazia. No entanto, muitos analisadores JSON aceitam valores primitivos também para input.

 var x; JSON.stringify(x); // will output "{}" 

Então sua resposta é "{}" que denota um object vazio.

Basta seguir os diagramas ferroviários dados na página json.org . [] e {} são os objects JSON mínimos válidos possíveis. Então a resposta é [] e {}.