Kann JSON mit "[" beginnen?

178

Nach dem , was ich auf json.org lesen kann , sollten alle JSON-Zeichenfolgen mit {(geschweifte Klammer) beginnen, und [Zeichen (eckige Klammern) repräsentieren ein Array-Element in JSON.

Ich benutze die json4jBibliothek und habe eine Eingabe erhalten, die mit beginnt [, sodass ich nicht dachte, dass dies ein gültiger JSON ist. Ich habe mir das JSON-Schema kurz angesehen, konnte aber nicht wirklich feststellen, dass eine JSON-Datei nicht [oder nur mit beginnen kann {.

Tiberiu
quelle
(Es gibt anscheinend mehrere schlecht gestaltete JSON-Bibliotheken, bei denen Sie den äußersten JSON-Typ kennen müssen. Die einfachste "Lösung" besteht darin, die JSON-Zeichenfolge damit zu umgeben [], sie als Array zu analysieren und das erste Array-Element zu verwenden.)
Hot Licks
Anscheinend ist es sicherer, es mit {und nicht [zu beginnen, damit es kein gültiges Javascript-Array ist und nicht für CSRF-Angriffe verwendet werden kann.
David Klempfner

Antworten:


218

JSON kann entweder ein Array oder ein Objekt sein. Speziell von json.org:

JSON basiert auf zwei Strukturen:

  • Eine Sammlung von Name / Wert-Paaren. In verschiedenen Sprachen wird dies als Objekt, Datensatz, Struktur, Wörterbuch, Hash-Tabelle, Schlüsselliste oder assoziatives Array realisiert.
  • Eine geordnete Liste von Werten. In den meisten Sprachen wird dies als
    Array, Vektor, Liste oder Sequenz realisiert.

Anschließend werden die beiden Strukturen wie folgt beschrieben: Ein JSON-Objekt Ein JSON-Array

Beachten Sie, dass die Start- und Endzeichen geschweifte Klammern bzw. eckige Klammern sind.

Bearbeiten
Und von hier aus: http://www.ietf.org/rfc/rfc4627.txt

Ein JSON-Text ist eine Folge von Token. Der Satz von Token enthält sechs strukturelle Zeichen, Zeichenfolgen, Zahlen und drei Literalnamen.

Ein JSON-Text ist ein serialisiertes Objekt oder Array.

Update (2014)

Ab März 2014 gibt es einen neuen JSON-RFC ( 7159 ), der die Definition geringfügig ändert (siehe Seite 4/5).

Die Definition gemäß RFC 4627 lautete: JSON-text = object / array

Dies wurde in RFC 7159 geändert in: JSON-text = ws value ws

Wobei wsLeerzeichen stehen und valuewie folgt definiert sind:

Ein JSON-Wert MUSS ein Objekt, ein Array, eine Zahl oder eine Zeichenfolge oder einer der folgenden drei Literalnamen sein:

false null true

Die Antwort auf die Frage lautet also immer noch Ja. JSON-Text kann mit einer eckigen Klammer (dh einem Array) beginnen. Aber zusätzlich zu Objekten und Arrays, kann es nun auch um eine Zahl, einen String oder die Werte false, nulloder true.

Dies hat sich auch gegenüber meinem vorherigen RFC 4627-Zitat geändert (Hervorhebung hinzugefügt):

Ein JSON-Text ist eine Folge von Token. Der Satz von Token enthält sechs strukturelle Zeichen, Zeichenfolgen, Zahlen und drei Literalnamen.

Ein JSON-Text ist ein serialisierter Wert . Beachten Sie, dass bestimmte frühere JSON-Spezifikationen einen JSON-Text als Objekt oder Array einschränkten. Implementierungen, die nur Objekte oder Arrays generieren, für die ein JSON-Text erforderlich ist, sind in dem Sinne interoperabel, dass alle Implementierungen diese als konforme JSON-Texte akzeptieren.


danke, ich schaue mir diese Zahl oft an, anscheinend gibt es ein Problem mit der json4j-Bibliothek, die einen json mit [nicht mag.
Tiberiu

1
@Tiberiu Hajas: Ich habe eine Weile gebraucht, um es zu verstehen, als ich es zum ersten Mal fand. Aber nachdem ich einige Beispiele von JSON gesehen und verglichen habe, gefällt mir wirklich, wie sie es gemacht haben. Json4j Bezüglich vielleicht können Sie einen Fehlerbericht zu den wichtigsten json4j Bibliothek einreichen Schöpfer .
Richard Marskell - Drackir

Ich bin wahrscheinlich zu spät zur Party. Was ich jedoch in RFC 8259 gefunden habe, besagt, dass ein JSON-Text eine Folge von Token ist, die aus Unicode-Codepunkten gebildet werden und der JSON-Wertgrammatik entsprechen. Der Satz von Token enthält sechs strukturelle Token, Zeichenfolgen, Zahlen und drei wörtliche Namens-Token. Das klingt so, als wäre so etwas legitim: {"1234"}, {true}. Was bedeutet dies jedoch? Dies ist kein Array, da es kein <code> [] </ code> gibt, und dies ist auch kein Objekt, da es zwei davon gibt.
Nicholas Humphrey
1
@NicholasHumphrey Was ich oben geschrieben habe, gilt immer noch für 8259. In demselben Abschnitt 2 (JSON-Grammatik) wird JSON-Text (auch bekannt als JSON-Dokument) wie folgt definiert: JSON-text = ws value ws"Ein JSON-Wert MUSS ein Objekt, ein Array, eine Zahl oder eine Zeichenfolge sein. oder einer der folgenden drei Literalnamen: false, null, true "gemäß Abschnitt 3 (Werte). Ihr Beispiel erfüllt diese Einschränkungen nicht und ist daher kein gültiger JSON.
Richard Marskell - Drackir

Antworten:

8

Wenn die Zeichenfolge, die Sie analysieren, mit einer linken Klammer ([) beginnt, können Sie JSONArray.parseein JSONArray-Objekt zurückholen und dann verwenden, get(i)wobei i ein Index von 0 bis zu den zurückgegebenen JSONArrays ist 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();
      }
   }
}

Welche produzierte Ausgabe wie:

{"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"}

Hinweis: Wenn Sie versuchen anzurufen JSONObject.parse(books.toString());, wird der folgende Fehler angezeigt:

java.io.IOException: Expecting '{' on line 1, column 2 instead, obtained token: 'Token: ['
Nathaniel Mills
quelle
1
Einfacherer Code könnte die Instanz von JSONArray im Vergleich zur Instanz von JSONObject für das vom get-Aufruf zurückgegebene Objekt verwenden, um zu bestimmen, welche Klasse zum Parsen des Objekts verwendet werden soll ...
Nathaniel Mills
5

JSON.ORG WEBSITE SAGT ....

https://www.json.org/

Auf der Website wird eindeutig Folgendes angegeben:

JSON basiert auf zwei Strukturen:

  1. Eine Sammlung von Name / Wert-Paaren. In verschiedenen Sprachen wird dies als Objekt, Datensatz, Struktur, Wörterbuch, Hash-Tabelle, Schlüsselliste oder assoziatives Array realisiert.

  2. Eine geordnete Liste von Werten. In den meisten Sprachen wird dies als Array, Vektor, Liste oder Sequenz realisiert.

Dies sind universelle Datenstrukturen. Praktisch alle modernen Programmiersprachen unterstützen sie in der einen oder anderen Form. Es ist sinnvoll, dass ein Datenformat, das mit Programmiersprachen austauschbar ist, auch auf diesen Strukturen basiert. In JSON nehmen sie folgende Formen an:

OBJEKT:

Ein Objekt ist eine ungeordnete Menge von Name / Wert-Paaren. Ein Objekt beginnt mit {(linke Klammer) und endet mit} (rechte Klammer). Auf jeden Namen folgt: (Doppelpunkt) und die Name / Wert-Paare werden durch (Komma) getrennt.

{string: value, string: value}

ARRAY:

Ein Array ist eine geordnete Sammlung von Werten. Ein Array beginnt mit [(linke Klammer) und endet mit] (rechte Klammer). Werte werden durch (Komma) getrennt.

[value, value, value ….]

WERT:

Ein Wert kann eine Zeichenfolge in doppelten Anführungszeichen oder eine Zahl oder wahr oder falsch oder null oder ein Objekt oder ein Array sein. Diese Strukturen können verschachtelt werden.

STRING:

Eine Zeichenfolge ist eine Folge von null oder mehr Unicode-Zeichen, die in doppelte Anführungszeichen gesetzt werden und Backslash-Escapezeichen verwenden. Ein Zeichen wird als einzelne Zeichenfolge dargestellt. Eine Zeichenfolge ist einer C- oder Java-Zeichenfolge sehr ähnlich.

NUMMER:

Eine Zahl ist einer C- oder Java-Zahl sehr ähnlich, außer dass die Oktal- und Hexadezimalformate nicht verwendet werden.

ÜBER WHITESPACE:

Zwischen jedem Token-Paar kann ein Leerzeichen eingefügt werden. Mit Ausnahme einiger Codierungsdetails beschreibt dies die Sprache vollständig.

J. Moreno
quelle
Gut mit den Beispielen; Es hat mir geholfen, meinen Unit-Test für einen JSON-Validator fertig zu schreiben. Ich war mir nicht sicher, was mit Zeichenfolge gemeint war (z. B. muss es sich um eine Zeichenfolge in doppelten Anführungszeichen handeln).
Gimlichael
Ich sehe, wie das verwirrt werden könnte, der Satz hätte etwas prägnanter sein können, angefangen wie folgt: "Eine Folge von null oder mehr Unicode-Zeichen ..." Ich glaube, der Autor hat ihn zur Hervorhebung hinzugefügt. Ich habe es so angelegt, dass es einfacher ist, einige der wichtigsten Punkte zu erkennen. Obwohl es sich um eine späte Antwort handelt, hoffe ich, dass dies bei Bedarf Klarheit schafft.
J. Moreno