Qual è il JSON minimo valido?


174

Ho letto attentamente la descrizione di JSON http://json.org/ ma non sono sicuro di conoscere la risposta alla semplice domanda. Quali stringhe sono il JSON valido minimo possibile?

  • "string" è la stringa valida JSON?
  • 42 il numero semplice è valido JSON?
  • true il valore booleano è un JSON valido?
  • {} l'oggetto vuoto è un JSON valido?
  • [] l'array vuoto è un JSON valido?

12
Test su jsonlint.com , gli ultimi due sono validi, gli altri no.
Ironcito,

1
alcuni parser JSON prevedono una matrice o un oggetto. Si lamentano solo di un numero o di una stringa.
Akonsu,

3
A partire da ora, quelli sono validi
Brian Colavito


risposta breve - {}
Tukaram Bhosale,

Risposte:


156

Al momento della stesura di questo documento, JSON è stato descritto esclusivamente in RFC4627 . Descrive (all'inizio di "2") un testo JSON come oggetto o array serializzato.

Ciò significa che solo {} e []sono stringhe JSON complete e complete in parser e stringificatori che aderiscono a tale standard.

Tuttavia , l'introduzione di ECMA-404 cambia ciò e i consigli aggiornati possono essere letti qui . Ho anche scritto un post sul blog sul problema.


Per confondere ulteriormente la questione, tuttavia, l' JSONoggetto (ad esempio JSON.parse()e JSON.stringify()) disponibile nei browser Web è standardizzato in ES5 e questo definisce chiaramente i testi JSON accettabili in questo modo:

Il formato di interscambio JSON utilizzato in questa specifica è esattamente quello descritto da RFC 4627 con due eccezioni:

  • La produzione JSONText di livello superiore della grammatica JSON ECMAScript può consistere in qualsiasi valore JSONValue anziché essere limitato a un oggetto JSONObray o JSON come specificato da RFC 4627.

  • snipped

Ciò significherebbe che tutti i valori JSON (inclusi stringhe, null e numeri) sono accettati dall'oggetto JSON, anche se l'oggetto JSON aderisce tecnicamente a RFC 4627.

Si noti quindi che è possibile stringere un numero in un browser conforme tramite JSON.stringify(5), che verrebbe rifiutato da un altro parser che aderisce a RFC4627, ma che non ha l'eccezione specifica elencata sopra. Ruby, ad esempio, sembrerebbe essere uno di questi esempi che accetta solo oggetti e matrici come radice . PHP, d'altra parte, aggiunge specificamente l'eccezione che "codificherà e decodificherà anche i tipi scalari e NULL".


@amdorra: puoi essere più specifico dove lo vedi?
Matt,

5
JSON non è un sostantivo, quindi "un JSON" non ha senso. Qualsiasi "valore JSON" è un "valore JSON", ma i parser spesso si aspettano un "testo JSON" come definito in tale RFC.
IMSoP,

2
mio male cancellerò la mia risposta allora
amdorra

1
@jmoreno Potresti chiarire il tuo commento per favore? Stai dicendo true, falseo nullda solo è un testo JSON valido? Potresti per favore citare una fonte, poiché ciò contraddice la maggior parte delle altre risposte / commenti qui?
Lawrence Johnston,

2
@jmoreno: Sicuramente la citazione dalla sezione 2 "Un testo JSON è un oggetto o un array serializzato." Si oppone? JSON Lint inoltre non ritiene che un non array o un oggetto siano validi. Non si discute se una stringa sia un valore letterale JSON valido; questo è se una stringa da sola è valida.
Matt,

42

Esistono almeno quattro documenti che possono essere considerati standard JSON su Internet. Gli RFC a cui si fa riferimento descrivono tutti il ​​tipo mime application/json. Ecco cosa ognuno ha da dire sui valori di livello superiore e se in cima è consentito qualsiasi cosa diversa da un oggetto o un array:

RFC-4627 : No.

Un testo JSON è una sequenza di token. L'insieme di token comprende sei caratteri strutturali, stringhe, numeri e tre nomi letterali.

Un testo JSON è un oggetto o un array serializzato.

JSON-text = oggetto / matrice

Si noti che RFC-4627 è stato contrassegnato come "informativo" rispetto a "standard proposto" e che è obsoleto da RFC-7159 , che a sua volta è obsoleto da RFC-8259.

RFC-8259 : Sì.

Un testo JSON è una sequenza di token. L'insieme di token comprende sei caratteri strutturali, stringhe, numeri e tre nomi letterali.

Un testo JSON è un valore serializzato. Si noti che alcune specifiche precedenti di JSON hanno vincolato un testo JSON a essere un oggetto o un array. Le implementazioni che generano solo oggetti o matrici in cui è richiesto un testo JSON saranno interoperabili nel senso che tutte le implementazioni accetteranno questi come testi JSON conformi.

JSON-text = valore ws ws

RFC-8259 è datato dicembre 2017 ed è contrassegnato con "INTERNET STANDARD".

ECMA-262 : Sì.

La grammatica sintattica JSON definisce un testo JSON valido in termini di token definiti dalla grammatica lessicale JSON. Il simbolo obiettivo della grammatica è JSONText.

Sintassi JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : Sì.

Un testo JSON è una sequenza di token formati da punti di codice Unicode conformi alla grammatica del valore JSON. L'insieme di token include sei token strutturali, stringhe, numeri e tre token letterali di nomi.


10

Secondo la vecchia definizione in RFC 4627 (che era stata obsoleta a marzo 2014 da RFC 7159), quelli erano tutti "valori JSON" validi, ma solo gli ultimi due avrebbero costituito un "testo JSON" completo:

Un testo JSON è un oggetto o un array serializzato.

A seconda del parser utilizzato, i soli "valori JSON" potrebbero essere accettati comunque. Ad esempio (attenendosi alla terminologia "valore JSON" vs "testo JSON"):

  • la JSON.parse()funzione ora standardizzata nei browser moderni accetta qualsiasi "valore JSON"
  • la funzione PHP è json_decodestata introdotta nella versione 5.2.0 accettando solo un intero "testo JSON", ma è stata modificata per accettare qualsiasi "valore JSON" nella versione 5.2.1
  • Python's json.loadsaccetta qualsiasi "valore JSON" secondo gli esempi in questa pagina di manuale
  • il validatore su http://jsonlint.com si aspetta un "testo JSON" completo
  • il modulo Ruby JSON accetterà solo un "testo JSON" completo (almeno secondo i commenti in questa pagina di manuale )

La distinzione è un po 'come la distinzione tra un "documento XML" e un "frammento XML", sebbene tecnicamente <foo />sia un documento XML ben formato (sarebbe meglio scritto come <?xml version="1.0" ?><foo />, ma come sottolineato nei commenti, la <?xmldichiarazione è tecnicamente facoltativa ).


Il confronto XML potrebbe essere inappropriato, poiché un documento XML è del tutto valido senza la dichiarazione XML facoltativa. Vedi la raccomandazione XML su w3.org/TR/xml/#sec-well-formed
Gunther

@Gunther Ah, sì, avevo dimenticato che è tecnicamente facoltativo, sebbene fortemente incoraggiato.
IMSoP,

@Gunther: A nitpick: <foo />è un documento XML ben formato , ma non valido . (Ma lo stesso vale <?xml version="1.0" ?><foo />.)
ruakh

@ruakh È interessante notare che la definizione qui implica che XML può essere "valido" solo nei confronti di un DTD, il che significa che pochissimi documenti XML lo sono, poiché i DTD sono scritti e dichiarati molto raramente in pratica (rispetto ai formati di definizione dello schema come XSD o RelaxNG) . Stavo verificando, perché se potessi essere valido su uno schema esterno, senza fare riferimento a esso, allora <foo /> potrebbe essere o meno valido su uno schema particolare , ma non è quello che afferma quello standard.
IMSoP,

4

La specifica ecma potrebbe essere utile come riferimento:

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

La funzione di analisi analizza un testo JSON (una stringa in formato JSON) e produce un valore ECMAScript. Il formato JSON è una forma limitata di letterale ECMAScript. Gli oggetti JSON sono realizzati come oggetti ECMAScript. Le matrici JSON sono realizzate come matrici ECMAScript. Stringhe, numeri, valori booleani e null JSON sono realizzati come stringhe ECMAScript, numeri, valori booleani e null. JSON utilizza un set più limitato di caratteri di spazio bianco rispetto a WhiteSpace e consente ai punti di codice Unicode U + 2028 e U + 2029 di apparire direttamente nei letterali JSONString senza utilizzare una sequenza di escape. Il processo di analisi è simile a 11.1.4 e 11.1.5 come vincolato dalla grammatica 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("[]"); // []

4
Sebbene sia un riferimento utile, questa è la specifica di un particolare parser JSON (quello definito nello standard ECMAScript) non per il formato stesso. json.org afferma esplicitamente che JSON è "completamente indipendente dalla lingua", quindi non esiste un parser corretto.
IMSoP,

1
JavaScript / ECMAScipt è l'ispirazione per JSON, e un utente di esso, ma non la "casa" di esso. JSON è stato derivato dalla notazione letterale dell'oggetto in (tutte le versioni precedenti di) ECMAScript, ma non è identico ad esso. La JSON.parsefunzione è stata quindi aggiunta alle versioni successive dello standard ECMAScript basato sulla grammatica di Crockford e RFC.
IMSoP,

4
Dovresti farloJSON.parse("\"string\"");
ericbn il

4

JSON è l'acronimo di JavaScript Object Notation. Solo {}e []definisce un oggetto Javascript. Gli altri esempi sono valori letterali. Ci sono tipi di oggetti in Javascript per lavorare con quei valori, ma l'espressione"string" è una rappresentazione del codice sorgente di un valore letterale e non di un oggetto.

Tieni presente che JSON non è Javascript. È una notazione che rappresenta i dati. Ha una struttura molto semplice e limitata. I dati JSON sono strutturati utilizzando{},:[] caratteri. Puoi usare solo valori letterali all'interno di quella struttura.

È perfettamente valido per un server rispondere con una descrizione dell'oggetto o un valore letterale. Tutti i parser JSON devono essere gestiti per gestire solo un valore letterale, ma solo un valore. JSON può rappresentare un solo oggetto alla volta. Quindi, affinché un server restituisca più di un valore, dovrebbe strutturarlo come un oggetto o un array.


1
Penso che avvicinarsi alla risposta da questa direzione offuschi più di quanto chiarisca: l'origine del nome non influisce sui dettagli dello standard e i tipi disponibili in JavaScript possono essere d'ispirazione per i tipi in JSON, ma non è necessario che corrispondono. L'introduzione su json.org lo chiarisce: "JSON è un formato di testo completamente indipendente dalla lingua"
IMSoP

@IMSoP Sono totalmente d'accordo. Ho mescolato i tipi Javascript con JSON e questo non è corretto. Aggiornerò la mia risposta.
Reactgular

2

Sì, sì, sì, sì e sì. Tutti sono valori letterali JSON validi.

Tuttavia, la RFC 4627 ufficiale afferma:

Un testo JSON è un oggetto o un array serializzato.

Quindi un intero "file" dovrebbe essere costituito da un oggetto o un array come struttura esterna, che ovviamente può essere vuota. Tuttavia, molti parser JSON accettano anche valori primitivi per l'input.


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

Quindi la tua risposta è "{}"che indica un oggetto vuoto.


FWIW, in Chrome, questo dà undefined, non "{}" `
Matt

-2

Segui semplicemente i diagrammi della ferrovia riportati nella pagina json.org . [] e {} sono gli oggetti JSON validi minimi possibili. Quindi la risposta è [] e {}.


3
Non è un FSM, è una grammatica. E non sembra indicare quale produzione sia la regola di partenza. Se le regole di partenza fossero arraye objectavresti ragione, ma è ragionevole aspettarsi valuedi essere l'inizio.

Mi sembra abbastanza semplice. Douglas Crockford li chiama così e partiamo sempre da sinistra e seguiamo le tracce a destra. La traccia più piccola fornisce il minimo JSON valido.
Hrishi,

2
Non è la tua interpretazione di una particolare regola grammaticale a cui mi oppongo, è che hai scelto due regole e presumi che una possa iniziare solo da quelle, non da altre. Se si osserva la valuesregola invece (o in aggiunta a) le regole arraye object, i numeri e le stringhe indipendenti sono un documento JSON valido.

-1. In primo luogo, come sottolinea @delnan, nulla nei diagrammi di json.org suggerisce che un testo JSON completo deve essere un oggetto o un array; hai scelto quei due in modo arbitrario, non basandoti su nulla su json.org. In secondo luogo, puntare sulla terminologia: []mentre un testo JSON valido sotto ogni specifica che abbia mai avuto un'opinione in merito, non è un "oggetto JSON valido", dal momento che non è un oggetto JSON. "Oggetto" in JSON si riferisce specificamente alla {}notazione; Le matrici JSON non sono oggetti JSON.
Mark Amery,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.