Was ist der minimal gültige JSON?

174

Ich habe die JSON-Beschreibung http://json.org/ sorgfältig gelesen , bin mir aber nicht sicher, ob ich die Antwort auf die einfache Frage kenne. Welche Zeichenfolgen sind das minimal mögliche gültige JSON?

  • "string" Ist die Zeichenfolge JSON gültig?
  • 42 Ist die einfache Zahl JSON gültig?
  • true Ist der boolesche Wert ein gültiger JSON?
  • {} Ist das leere Objekt ein gültiger JSON?
  • [] Ist das leere Array ein gültiger JSON?
Bessarabov
quelle
12
Beim Testen auf jsonlint.com sind die letzten beiden gültig, die anderen nicht.
Ironcito
1
Einige JSON-Parser erwarten ein Array oder ein Objekt. Sie beschweren sich nur über eine Zahl oder eine Zeichenfolge.
Akonsu
3
Ab sofort sind diese gültig
Brian Colavito
kurze Antwort - {}
Tukaram Bhosale

Antworten:

156

Zum Zeitpunkt des Schreibens war JSON ausschließlich in RFC4627 beschrieben . Es beschreibt (am Anfang von "2") einen JSON-Text als ein serialisiertes Objekt oder Array.

Dies bedeutet , dass nur {} und []gültig, komplett JSON - Strings in Parsern und stringifiers diesen Standard beitretenden sind.

Die Einführung von ECMA-404 ändert dies jedoch, und die aktualisierten Hinweise können hier gelesen werden . Ich habe auch einen Blog-Beitrag zu diesem Thema geschrieben.


Um die Angelegenheit jedoch weiter zu verwirren, ist das in Webbrowsern verfügbare JSONObjekt (z. B. JSON.parse()und JSON.stringify()) in ES5 standardisiert , und dies definiert die akzeptablen JSON-Texte wie folgt klar:

Das in dieser Spezifikation verwendete JSON-Austauschformat ist mit zwei Ausnahmen genau das von RFC 4627 beschriebene:

  • Die JSONText-Produktion der obersten Ebene der ECMAScript-JSON-Grammatik kann aus einem beliebigen JSONValue bestehen, anstatt darauf beschränkt zu sein, ein JSONObject oder ein JSONArray zu sein, wie in RFC 4627 angegeben.

  • schnippte

Dies würde bedeuten, dass alle JSON-Werte (einschließlich Zeichenfolgen, Nullen und Zahlen) vom JSON-Objekt akzeptiert werden, obwohl das JSON-Objekt technisch RFC 4627 entspricht.

Beachten Sie, dass Sie daher eine Nummer in einem konformen Browser über kennzeichnen können JSON.stringify(5), die von einem anderen Parser abgelehnt wird, der RFC4627 entspricht, für den jedoch die oben aufgeführte spezifische Ausnahme nicht gilt. Ruby zum Beispiel scheint ein solches Beispiel zu sein, das nur Objekte und Arrays als Root akzeptiert . PHP hingegen fügt ausdrücklich die Ausnahme hinzu, dass "es auch Skalartypen und NULL codiert und decodiert".

Matt
quelle
@amdorra: Kannst du genauer sagen, wo du das siehst?
Matt
5
JSON ist kein Substantiv, daher ist "ein JSON" bedeutungslos. Jeder "JSON-Wert" ist ein "JSON-Wert", aber Parser erwarten häufig einen "JSON-Text", wie in diesem RFC definiert.
IMSoP
2
mein schlechtes ich werde meine Antwort dann löschen
amdorra
1
@jmoreno Könnten Sie bitte Ihren Kommentar klarstellen? Wollen Sie damit sagen true, falseoder ist nullallein ein gültiger JSON-Text? Könnten Sie bitte eine Quelle angeben, da dies den meisten anderen Antworten / Kommentaren hier widerspricht?
Lawrence Johnston
2
@jmoreno: Sicherlich das Zitat aus Abschnitt 2 "Ein JSON-Text ist ein serialisiertes Objekt oder Array." Widersetzt sich das? JSON Lint glaubt auch nicht, dass ein Nicht-Array oder Objekt gültig ist. Es gibt keine Debatte darüber, ob eine Zeichenfolge ein gültiges JSON-Literal ist. Dies ist vorbei, ob eine Zeichenfolge für sich gültig ist.
Matt
42

Es gibt mindestens vier Dokumente, die im Internet als JSON-Standards gelten können. Die RFCs, auf die alle verwiesen werden, beschreiben den MIME-Typ application/json. Hier ist, was jeder über die Werte der obersten Ebene zu sagen hat und ob oben etwas anderes als ein Objekt oder ein Array zulässig ist:

RFC-4627 : Nein.

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.

JSON-Text = Objekt / Array

Beachten Sie, dass RFC-4627 im Gegensatz zu "vorgeschlagener Standard" als "informativ" gekennzeichnet wurde und dass es durch RFC-7159 veraltet ist, das wiederum durch RFC-8259 veraltet ist.

RFC-8259 : Ja.

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.

JSON-Text = ws Wert ws

RFC-8259 ist vom Dezember 2017 datiert und mit "INTERNET STANDARD" gekennzeichnet.

ECMA-262 : Ja.

Die JSON-Syntaktische Grammatik definiert einen gültigen JSON-Text in Form von Token, die durch die lexikalische JSON-Grammatik definiert werden. Das Zielsymbol der Grammatik ist JSONText.

Syntax JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : Ja.

Ein JSON-Text ist eine Folge von Token, 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.

Johann
quelle
10

Nach der alten Definition in RFC 4627 (die im März 2014 von RFC 7159 überholt wurde) waren dies alles gültige "JSON-Werte", aber nur die letzten beiden würden einen vollständigen "JSON-Text" darstellen:

Ein JSON-Text ist ein serialisiertes Objekt oder Array.

Abhängig vom verwendeten Parser werden die einzelnen "JSON-Werte" möglicherweise trotzdem akzeptiert. Zum Beispiel (Festhalten an der Terminologie "JSON-Wert" vs. "JSON-Text"):

  • Die JSON.parse()jetzt in modernen Browsern standardisierte Funktion akzeptiert jeden "JSON-Wert".
  • Die PHP-Funktion json_decodewurde in Version 5.2.0 eingeführt und akzeptiert nur einen ganzen "JSON-Text", wurde jedoch geändert, um jeden "JSON-Wert" in Version 5.2.1 zu akzeptieren
  • Python json.loadsakzeptiert jeden "JSON-Wert" gemäß den Beispielen auf dieser Handbuchseite
  • Der Validator unter http://jsonlint.com erwartet einen vollständigen "JSON-Text".
  • Das Ruby JSON-Modul akzeptiert nur einen vollständigen "JSON-Text" (zumindest gemäß den Kommentaren auf dieser Handbuchseite ).

Die Unterscheidung ähnelt der Unterscheidung zwischen einem "XML-Dokument" und einem "XML-Fragment", obwohl es sich technisch gesehen <foo />um ein wohlgeformtes XML-Dokument handelt (es wäre besser geschrieben <?xml version="1.0" ?><foo />, aber wie in den Kommentaren erwähnt, ist die <?xmlDeklaration technisch optional ).

IMSoP
quelle
Der XML-Vergleich ist möglicherweise unangemessen, da ein XML-Dokument ohne die optionale XML-Deklaration vollständig gültig ist. Siehe die XML-Empfehlung unter w3.org/TR/xml/#sec-well-formed
Gunther
@Gunther Ah, ja, ich hatte vergessen, dass es technisch optional ist, obwohl sehr ermutigt.
IMSoP
@Gunther: Ein Nitpick: <foo />ist ein wohlgeformtes XML-Dokument, aber kein gültiges . (Aber das gleiche gilt für <?xml version="1.0" ?><foo />.)
Ruakh
@ruakh Interessanterweise impliziert die Definition hier , dass XML nur für eine DTD "gültig" sein kann, was bedeutet, dass nur sehr wenige XML-Dokumente vorhanden sind, da DTDs in der Praxis sehr selten geschrieben und deklariert werden (im Vergleich zu Schemadefinitionsformaten wie XSD oder RelaxNG). . Ich habe nachgeprüft, denn wenn Sie für ein externes Schema gültig sein könnten, ohne darauf zu verweisen, <foo /> könnte dies für ein bestimmtes Schema gültig sein oder nicht , aber das ist nicht das, was dieser Standard angibt.
IMSoP
4

Die Ecma-Spezifikation kann als Referenz nützlich sein:

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

Die Analysefunktion analysiert einen JSON-Text (eine JSON-formatierte Zeichenfolge) und erzeugt einen ECMAScript-Wert. Das JSON-Format ist eine eingeschränkte Form des ECMAScript-Literal. JSON-Objekte werden als ECMAScript-Objekte realisiert. JSON-Arrays werden als ECMAScript-Arrays realisiert. JSON-Zeichenfolgen, Zahlen, Boolesche Werte und Null werden als ECMAScript-Zeichenfolgen, Zahlen, Boolesche Werte und Null realisiert. JSON verwendet einen begrenzteren Satz von Leerzeichen als WhiteSpace und ermöglicht, dass Unicode-Codepunkte U + 2028 und U + 2029 direkt in JSONString-Literalen angezeigt werden, ohne eine Escape-Sequenz zu verwenden. Der Analyseprozess ähnelt 11.1.4 und 11.1.5, wie durch die JSON-Grammatik eingeschränkt.

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.
quelle
4
Dies ist zwar eine nützliche Referenz, aber die Spezifikation eines bestimmten JSON-Parsers (der im ECMAScript-Standard definierten), nicht für das Format selbst. json.org gibt ausdrücklich an, dass JSON "vollständig sprachunabhängig " ist, sodass es keinen richtigen Parser gibt.
IMSoP
1
JavaScript / ECMAScipt ist die Inspiration für JSON und ein Benutzer davon, aber nicht die "Heimat" davon. JSON wurde aus der Objektliteralnotation in (allen früheren Versionen von) ECMAScript abgeleitet, ist jedoch nicht identisch damit. Die JSON.parseFunktion wurde dann späteren Versionen des ECMAScript-Standards hinzugefügt, die auf der Crockford-Grammatik und dem RFC basieren.
IMSoP
4
Sie sollten tunJSON.parse("\"string\"");
ericbn
4

JSON steht für JavaScript Object Notation. Nur {}und []definieren Sie ein Javascript-Objekt. Die anderen Beispiele sind Werteliterale. In Javascript gibt es Objekttypen für die Arbeit mit diesen Werten, aber der Ausdruck "string"ist eine Quellcodedarstellung eines Literalwerts und kein Objekt.

Beachten Sie, dass JSON kein Javascript ist. Es ist eine Notation, die Daten darstellt. Es hat eine sehr einfache und begrenzte Struktur. JSON-Daten sind mit {},:[]Zeichen strukturiert . Sie können nur Literalwerte innerhalb dieser Struktur verwenden.

Es ist vollkommen gültig, dass ein Server entweder mit einer Objektbeschreibung oder einem Literalwert antwortet. Alle JSON-Parser sollten so behandelt werden, dass sie nur einen Literalwert, aber nur einen Wert verarbeiten. JSON kann jeweils nur ein Objekt darstellen. Damit ein Server mehr als einen Wert zurückgeben kann, muss er ihn als Objekt oder Array strukturieren.

Reactgular
quelle
1
Ich denke, die Antwort aus dieser Richtung zu trüben, trübt mehr als es verdeutlicht: Die Herkunft des Namens hat keinen Einfluss auf die Details des Standards, und die in JavaScript verfügbaren Typen können eine Inspiration für die Typen in JSON sein, aber es gibt keine Anforderung dass sie zusammenpassen. Die Einführung auf json.org macht dies deutlich: "JSON ist ein Textformat, das vollständig
sprachunabhängig
@IMSoP Ich stimme vollkommen zu. Ich habe Javascript-Typen mit JSON gemischt und das ist nicht korrekt. Ich werde meine Antwort aktualisieren.
Reactgular
2

Ja, ja, ja, ja und ja. Alle von ihnen sind gültige JSON-Werteliterale.

Der offizielle RFC 4627 besagt jedoch:

Ein JSON-Text ist ein serialisiertes Objekt oder Array.

Eine ganze "Datei" sollte also aus einem Objekt oder Array als äußerster Struktur bestehen, die natürlich leer sein kann. Viele JSON-Parser akzeptieren jedoch auch primitive Werte für die Eingabe.

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

Ihre Antwort lautet also, "{}"was ein leeres Objekt bezeichnet.

Jani Hyytiäinen
quelle
FWIW, In Chrome gibt dies undefinednicht "{}" `
Matt
-2

Folgen Sie einfach den Eisenbahndiagrammen auf der Seite json.org . [] und {} sind die minimal möglichen gültigen JSON-Objekte. Die Antwort lautet also [] und {}.

Hrishi
quelle
3
Es ist kein FSM, es ist eine Grammatik. Und es scheint nicht darauf hinzudeuten, welche Produktion die Startregel ist. Wenn die Startregeln wären arrayund objectSie Recht hätten, ist es vernünftig zu erwarten value, dass dies der Start ist.
Sieht für mich allerdings ziemlich einfach aus. Douglas Crockford nennt sie so und wir beginnen immer von links und folgen den Spuren nach rechts. Die kleinste Spur gibt den minimal gültigen JSON an.
Hrishi
2
Es ist nicht Ihre Interpretation einer bestimmten Grammatikregel, gegen die ich Einwände habe, sondern dass Sie zwei Regeln gewählt haben und davon ausgehen, dass eine nur von diesen ausgehen kann, nicht von anderen. Wenn Sie sich die valuesRegel stattdessen (oder zusätzlich zu) den Regeln arrayund ansehen object, sind eigenständige Zahlen und Zeichenfolgen ein gültiges JSON-Dokument.
-1. Erstens, wie @delnan hervorhebt, deutet nichts in den Diagrammen auf json.org darauf hin, dass ein vollständiger JSON-Text ein Objekt oder Array sein muss. Sie haben diese beiden willkürlich ausgewählt und basieren nicht auf irgendetwas auf json.org. Zweitens: Nitpicking über Terminologie: []Während ein gültiger JSON-Text unter jeder Spezifikation, die jemals eine Meinung zu diesem Thema hatte, kein "gültiges JSON-Objekt" ist, da es sich nicht um ein JSON-Objekt handelt. "Objekt" in JSON bezieht sich speziell auf die {}Notation; JSON-Arrays sind keine JSON-Objekte.
Mark Amery