Qual é o JSON mínimo válido?

174

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

  • "string" a string é JSON válida?
  • 42 o número simples é válido JSON?
  • true o valor booleano é um JSON válido?
  • {} o objeto vazio é um JSON válido?
  • [] a matriz vazia é um JSON válido?
bessarabov
fonte
12
Testando em jsonlint.com , os dois últimos são válidos, os outros não.
ironcito
1
alguns analisadores JSON esperam uma matriz ou um objeto. Eles reclamam de apenas um número ou uma string.
Akonsu
3
A partir de agora, essas são válidas #
Brian Colavito 07/07
resposta curta - {}
Tukaram Bhosale

Respostas:

156

No momento da redação deste artigo, o JSON era descrito apenas no RFC4627 . Ele descreve (no início de "2") um texto JSON como um objeto ou matriz serializada.

Isso significa que apenas {} e []são válidas, as strings JSON completas nos analisadores e stringifiers que aderem a esse padrão.

No entanto , a introdução do ECMA-404 altera isso e os conselhos atualizados podem ser lidos aqui . Também escrevi um post sobre o assunto.


No entanto, para confundir ainda mais o assunto, o JSONobjeto (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 pelo 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 se restringir a ser um JSONObject ou JSONArray, conforme especificado pelo RFC 4627.

  • cortada

Isso significa que todos os valores JSON (incluindo cadeias, valores nulos e números) são aceitos pelo objeto JSON, mesmo que o objeto JSON tecnicamente esteja em conformidade com o RFC 4627.

Observe que, portanto, você pode especificar um número em um navegador conforme 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 objetos e matrizes como raiz . Por outro lado, o PHP adiciona especificamente a exceção de que "ele também codifica e decodifica os tipos escalares e NULL".

Matt
fonte
@amdorra: Você pode ser mais específico onde está vendo isso?
24513 Matt
5
JSON não é um substantivo, portanto, "um JSON" não faz sentido. Qualquer "valor JSON" é um "valor JSON", mas os analisadores geralmente esperam um "texto JSON", conforme definido na RFC.
IMSoP
2
meu mau eu vou apagar a minha resposta, então
amdorra
1
@jmoreno Você poderia esclarecer seu comentário? Você está dizendo true, falseou nullpor si só é um texto JSON válido? Você poderia citar uma fonte, pois isso contradiz a maioria das outras respostas / comentários aqui?
Lawrence Johnston
2
@jmoreno: Certamente a citação da seção 2 "Um texto JSON é um objeto ou matriz serializada." Se opõe a isso? O JSON Lint também não considera válido um objeto ou não array. Não há debate sobre se uma string é um literal JSON válido; isso significa se uma string por si só é válida.
26513 Matt
42

Há pelo menos quatro documentos que podem ser considerados padrões JSON na Internet. Todos os RFCs mencionados descrevem o tipo MIME application/json. Aqui está o que cada um tem a dizer sobre os valores de nível superior e se algo além de um objeto 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, cadeias, números e três nomes literais.

Um texto JSON é um objeto ou matriz serializada.

JSON-text = objeto / matriz

Observe que o RFC-4627 foi marcado como "informativo" em oposição ao "padrão proposto" e que é 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, cadeias, números e três nomes literais.

Um texto JSON é um valor serializado. Observe que certas especificações anteriores do JSON restringiam um texto JSON a ser um objeto ou uma matriz. Implementações que geram apenas objetos ou matrizes nas quais um texto JSON é solicitado serão interoperáveis ​​no sentido de que todas as implementações os aceitarão como textos JSON em conformidade.

JSON-text = valor ws ws

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

ECMA-262 : Sim.

A gramática sintática JSON define um texto JSON válido em termos de tokens definidos pela gramática lexical 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 valor JSON. O conjunto de tokens inclui seis tokens estruturais, cadeias, números e três tokens de nome literal.

Johann
fonte
10

De acordo com a definição antiga na RFC 4627 (que foi obsoleta em março de 2014 pela RFC 7159), todos esses eram "valores JSON" válidos, mas apenas os dois últimos constituiriam um "texto JSON" completo:

Um texto JSON é um objeto ou matriz serializada.

Dependendo do analisador usado, os "valores JSON" únicos podem ser aceitos de qualquer maneira. Por exemplo (aderindo à terminologia "valor JSON" vs "texto JSON"):

  • a JSON.parse()função agora padronizada em navegadores modernos aceita qualquer "valor JSON"
  • a função PHP json_decodefoi introduzida na versão 5.2.0, aceitando apenas um "texto JSON" inteiro, mas foi alterada para aceitar qualquer "valor JSON" na versão 5.2.1
  • O Python json.loadsaceita qualquer "valor JSON" de acordo com 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 de manual )

A distinção é um pouco como a distinção entre um "documento XML" e um "fragmento XML", embora tecnicamente <foo />seja um documento XML bem formado (seria melhor escrever como <?xml version="1.0" ?><foo />, mas como indicado nos comentários, a <?xmldeclaração é tecnicamente opcional )

IMSoP
fonte
A comparação XML pode ser inadequada, porque um documento XML é totalmente válido sem a declaração XML opcional. Veja a recomendação XML em w3.org/TR/xml/#sec-well-formed
Gunther
@ Gunther Ah, sim, eu tinha esquecido que é tecnicamente opcional, embora altamente incentivado.
IMSoP
@ Gunther: Um nitpick: <foo />é um documento XML bem formado , mas não é válido . (Mas o mesmo é verdade para <?xml version="1.0" ?><foo />.)
ruach
@ruakh Curiosamente, a definição aqui implica que o XML só pode ser "válido" em relação a uma DTD, o que significa que poucos documentos XML são, pois as DTDs são muito raramente escritas e declaradas na prática (em comparação com os formatos de definição de esquema, como XSD ou RelaxNG) . Eu estava checando, porque se você pode ser válido em um esquema externo, sem referenciá-lo, <foo /> pode ou não ser válido em um esquema específico , mas não é isso que esse padrão declara.
IMSoP
4

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

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

A função de análise analisa um texto JSON (uma String no formato JSON) e produz um valor ECMAScript. O formato JSON é uma forma restrita de literal ECMAScript. Objetos JSON são realizados como objetos ECMAScript. Matrizes JSON são realizadas como matrizes ECMAScript. Strings, números, booleanos e nulos JSON são realizados como Strings, Numbers, Booleans e nulos do ECMAScript. O JSON usa um conjunto mais limitado de caracteres de espaço em branco 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 sequência de escape. O processo de análise é semelhante ao 11.1.4 e 11.1.5, conforme restrito 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("[]"); // []
Emil A.
fonte
4
Embora seja uma referência útil, essa é a especificação de um analisador JSON específico (aquele definido no padrão ECMAScript) e não para o formato em si. O json.org afirma explicitamente que o JSON é "completamente independente da linguagem", portanto não há um analisador correto.
IMSoP
1
JavaScript / ECMAScipt é a inspiração para o JSON e um usuário, mas não a "casa" dele. O JSON foi derivado da notação literal do objeto em (todas as versões anteriores do) ECMAScript, mas não é idêntico a ele. A JSON.parsefunção foi adicionada às versões posteriores do padrão ECMAScript com base na gramática de Crockford e na RFC.
IMSoP
4
Você deve fazerJSON.parse("\"string\"");
ericbn
4

JSON significa JavaScript Object Notation. Somente {}e []defina um objeto Javascript. Os outros exemplos são literais de valor. Existem tipos de objeto 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 de um objeto.

Lembre-se de que JSON não é Javascript. É uma notação que representa dados. Possui 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 do objeto ou um valor literal. Todos os analisadores JSON devem ser manipulados para manipular apenas um valor literal, mas apenas um valor. JSON pode representar apenas um único objeto de cada vez. Portanto, para um servidor retornar mais de um valor, seria necessário estruturá-lo como um objeto ou uma matriz.

Reactgular
fonte
1
Eu acho que abordar a resposta dessa direção atrapalha mais do que esclarece: a origem do nome não tem relação com os detalhes do padrão, e os tipos disponíveis em JavaScript podem ser uma inspiração para os tipos em JSON, mas não há requisitos que eles combinam. A introdução no json.org deixa isso claro: "JSON é um formato de texto completamente independente do idioma"
IMSoP 24/13
@IMSoP Eu concordo totalmente. Misturei tipos de Javascript com JSON e isso não está correto. Vou atualizar minha resposta.
Reactgular
2

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

No entanto, a RFC 4627 oficial declara:

Um texto JSON é um objeto ou matriz serializada.

Portanto, um "arquivo" inteiro deve consistir em um objeto ou matriz como a estrutura mais externa, que obviamente pode estar vazia. No entanto, muitos analisadores JSON também aceitam valores primitivos para entrada.

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

Portanto, sua resposta é "{}"qual denota um objeto vazio.

Jani Hyytiäinen
fonte
FWIW, no Chrome, isso dá undefined, não "{}" `#
248
-2

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

Hrishi
fonte
3
Não é um FSM, é uma gramática. E isso não parece indicar qual produção é a regra de início. Se as regras de início fossem arraye objectvocê estaria certo, mas é razoável esperar valueque seja o começo.
Parece bastante simples para mim. Douglas Crockford os chama assim e sempre começamos da esquerda e seguimos os trilhos para a direita. A faixa menor fornece o JSON mínimo válido.
precisa saber é o seguinte
2
Não é sua interpretação de nenhuma regra gramatical em particular que eu me oponho, é que você escolheu duas regras e presume que uma pode apenas começar com essas e não com outras. Se você observar a valuesregra (ou além) das regras arraye object, os números e as cadeias independentes serão um documento JSON válido.
-1. Primeiramente, como o @delnan aponta, nada nos diagramas do json.org sugere que um texto JSON completo deve ser um objeto ou matriz; você escolheu esses dois arbitrariamente, não com base em nada no json.org. Em segundo lugar, analisar a terminologia: []embora um texto JSON válido em todas as especificações que já teve uma opinião sobre o assunto, não seja um "objeto JSON válido", pois não é um objeto JSON. "Objeto" em JSON refere-se especificamente à {}notação; Matrizes JSON não são objetos JSON.
Mark Amery