JSON può iniziare con "["?


178

Da quello che posso leggere su json.org , tutte le stringhe JSON dovrebbero iniziare con {(parentesi graffa) e i [caratteri (parentesi quadre) rappresentano un elemento array in JSON.

Uso la json4jlibreria e ho ricevuto un input che inizia con [, quindi non pensavo fosse un JSON valido. Ho esaminato brevemente lo schema JSON, ma non sono riuscito a trovarlo affermando che un file JSON non può iniziare [o che può solo iniziare {.


(Apparentemente ci sono diverse librerie JSON mal progettate che richiedono di conoscere il tipo JSON più esterno. La "correzione" più semplice qui è di circondare la stringa JSON [], analizzarla come un array e prendere il primo elemento array.)
Hot Licks il

Apparentemente è più sicuro iniziare con {e non [in modo che non sia un array Javascript valido e non possa essere utilizzato per gli attacchi CSRF.
David Klempfner,

Risposte:


218

JSON può essere un array o un oggetto. In particolare su json.org:

JSON è costruito su due strutture:

  • Una raccolta di coppie nome / valore. In varie lingue, questo viene realizzato come oggetto, record, struct, dizionario, tabella hash, elenco con chiave o array associativo.
  • Un elenco ordinato di valori. Nella maggior parte delle lingue, questo è realizzato come una
    matrice, un vettore, un elenco o una sequenza.

Quindi continua descrivendo le due strutture come: Un oggetto JSON Un array JSON

Si noti che i caratteri iniziale e finale sono rispettivamente parentesi graffe e parentesi quadre.

Modifica
E da qui: http://www.ietf.org/rfc/rfc4627.txt

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.

Aggiornamento (2014)

A partire da marzo 2014, esiste un nuovo JSON RFC ( 7159 ) che modifica leggermente la definizione (vedere le pagine 4/5).

La definizione per RFC 4627 era: JSON-text = object / array

Questo è stato modificato in RFC 7159 in: JSON-text = ws value ws

Dove wsrappresenta gli spazi bianchi ed valueè definito come segue:

Un valore JSON DEVE essere un oggetto, un array, un numero o una stringa o uno dei seguenti tre nomi letterali:

false null true

Quindi, la risposta alla domanda è ancora sì, il testo JSON può iniziare con una parentesi quadra (ovvero una matrice). Ma oltre agli oggetti e array, ora può essere anche un numero, una stringa o valori false, nullo true.

Inoltre, questo è cambiato dalla mia precedente citazione RFC 4627 (enfasi aggiunta):

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.


grazie, guardo quella figura molte volte, apparentemente c'è un problema con la libreria json4j, che non ama un json con [.
Tiberiu,

1
@Tiberiu Hajas: mi ci è voluto un po 'di tempo per capirlo quando l'ho trovato per la prima volta. Ma dopo aver visto alcuni esempi di JSON e averli confrontati, mi piace molto come lo hanno fatto. Per quanto riguarda json4j, forse puoi inviare una segnalazione di bug al creatore della libreria json4j .
Richard Marskell - Drackir,

Probabilmente sono in ritardo per la festa. Ma quello che ho trovato in RFC 8259 afferma che un testo JSON è una sequenza di token formata da punti di codice Unicode che è conforme alla grammatica del valore JSON. L'insieme di token include sei token strutturali, stringhe, numeri e tre token letterali di nomi. Questo suona come qualcosa del genere è legittimo: {"1234"}, {true}. Tuttavia cosa rappresenta questo? Questo non è un array, perché non c'è <code> [] </code>, né questo è un oggetto, perché ce ne sono due.
Nicholas Humphrey,

1
@NicholasHumphrey Ciò che ho scritto sopra si applica ancora nell'8259. Nella stessa sezione 2 (JSON Grammar) il testo JSON (aka un documento JSON) è definito come: JSON-text = ws value wsdove "Un valore JSON DEVE essere un oggetto, un array, un numero o una stringa, o uno dei seguenti tre nomi letterali: false, null, true "per Sezione 3 (Valori). Il tuo esempio non soddisfa tali vincoli e quindi non è JSON valido.
Richard Marskell - Drackir,

8

Se la stringa che stai analizzando inizia con una parentesi graffa sinistra ([) puoi usare JSONArray.parseper recuperare un oggetto JSONArray e quindi puoi usare get(i)dove i è un indice da 0 a quello restituito da JSONArray size()-1.

import java.io.IOException;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;

public class BookListTest {
   public static void main(String[] args) {
      String jsonBookList = "{\"book_list\":{\"book\":[{\"title\":\"title 1\"},{\"title\":\"title 2\"}]}}";
      Object book_list;
      try {
         book_list = JSONObject.parse(jsonBookList);
         System.out.println(book_list);
         Object bookList = JSONObject.parse(book_list.toString()).get("book_list");
         System.out.println(bookList);
         Object books = JSONObject.parse(bookList.toString()).get("book");
         System.out.println(books);
         JSONArray bookArray = JSONArray.parse(books.toString());
         for (Object book : bookArray) {
            System.out.println(book);
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Che ha prodotto output come:

{"book_list":{"book":[{"title":"title 1"},{"title":"title 2"}]}}
{"book":[{"title":"title 1"},{"title":"title 2"}]}
[{"title":"title 1"}, {"title":"title 2"}]
{"title":"title 1"}
{"title":"title 2"}

Nota: se si tenta di chiamare JSONObject.parse(books.toString());si otterrà l'errore riscontrato:

java.io.IOException: Expecting '{' on line 1, column 2 instead, obtained token: 'Token: ['

1
Un codice più semplice potrebbe usare istanza di JSONArray contro istanza di JSONObject sull'oggetto restituito dalla chiamata get per determinare quale classe deve essere utilizzata per analizzare l'oggetto ...
Nathaniel Mills

5

IL SITO JSON.ORG DICE ....

https://www.json.org/

Il sito afferma chiaramente quanto segue:

JSON è costruito su due strutture:

  1. Una raccolta di coppie nome / valore. In varie lingue, questo viene realizzato come oggetto, record, struct, dizionario, tabella hash, elenco con chiave o array associativo.

  2. Un elenco ordinato di valori. Nella maggior parte delle lingue, questo viene realizzato come una matrice, un vettore, un elenco o una sequenza.

Queste sono strutture di dati universali. Praticamente tutti i moderni linguaggi di programmazione li supportano in un modo o nell'altro. È logico che un formato di dati intercambiabile con i linguaggi di programmazione si basi anche su queste strutture. In JSON, assumono queste forme:

OGGETTO:

Un oggetto è un insieme non ordinato di coppie nome / valore. Un oggetto inizia con {(parentesi graffa sinistra) e termina con} (parentesi graffa destra). Ogni nome è seguito da: (due punti) e le coppie nome / valore sono separate da, (virgola).

{string: value, string: value}

VETTORE:

Un array è una raccolta ordinata di valori. Un array inizia con [(parentesi quadra sinistra) e termina con] (parentesi quadra destra). I valori sono separati da, (virgola).

[value, value, value ….]

VALORE:

Un valore può essere una stringa tra virgolette doppie, oppure un numero, oppure true o false o null, oppure un oggetto o un array. Queste strutture possono essere nidificate.

CORDA:

Una stringa è una sequenza di zero o più caratteri Unicode, racchiusi tra virgolette doppie, con escape di barra rovesciata. Un carattere è rappresentato come una singola stringa di caratteri. Una stringa è molto simile a una stringa C o Java.

NUMERO:

Un numero è molto simile a un numero C o Java, tranne per il fatto che i formati ottali ed esadecimali non vengono utilizzati.

INFORMAZIONI SU WHITESPACE:

Gli spazi bianchi possono essere inseriti tra qualsiasi coppia di token. Tranne alcuni dettagli di codifica, che descrive completamente la lingua.


Buono con gli esempi; mi ha aiutato a finire di scrivere il mio test unitario per un validatore JSON. Non ero sicuro di cosa si intendesse per stringa (es. Deve essere una stringa tra virgolette doppie).
gimlichael,

Vedo come ciò possa essere confuso, la frase avrebbe potuto essere un po 'più concisa a partire dal seguente: "Una sequenza di zero o più caratteri Unicode ...." Credo che l'autore possa averla aggiunta per enfasi. L'ho strutturato in modo da rendere più semplice la visualizzazione di alcuni dei punti chiave. Sebbene una risposta tardiva, spero che aggiunga un po 'di chiarezza se necessario.
J. Moreno,
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.