有効な最小JSONは何ですか?


174

JSONの説明http://json.org/を注意深く読みましたが、簡単な質問に対する答えがわかりません。最小限の有効なJSONとはどのような文字列ですか?

  • "string" 文字列は有効なJSONですか?
  • 42 単純な数字は有効なJSONですか?
  • true ブール値は有効なJSONですか?
  • {} 空のオブジェクトは有効なJSONですか?
  • [] 空の配列は有効なJSONですか?

12
jsonlint.comでのテストでは、最後の2つは有効ですが、他の2つは無効です。
ironcito 2013

1
一部のJSONパーサーは、配列またはオブジェクトを想定しています。彼らはただの数字や文字列について文句を言う。
akonsu 2013

3
現在のところ、これらは有効です
Brian Colavito 2016


短い答え-{}
Tukaram Bhosale

回答:


156

執筆時点では、JSONはRFC4627でのみ説明されていました。JSONテキストを( "2"の先頭で)シリアル化されたオブジェクトまたは配列として記述します。

この手段のみ {}[]パーサとその標準に準拠stringifiersで有効な、完全なJSON文字列です。

ただし、ECMA-404の導入によりそれが変更され、更新されたアドバイスはここで読むことができます。この問題に関するブログ投稿書いています。


ただし、問題をさらに混乱させるために、Webブラウザーで使用できるJSONオブジェクト(例:JSON.parse()およびJSON.stringify()はES5標準化されており、次のように、受け入れ可能なJSONテキストを明確に定義しています。

この仕様で使用されるJSON交換形式は、RFC 4627で説明されている形式とまったく同じですが、次の2つの例外があります。

  • ECMAScript JSON文法の最上位のJSONText生成は、RFC 4627で指定されているJSONObjectまたはJSONArrayに制限されるのではなく、任意のJSONValueで構成できます。

  • 切り落とした

つまり、JSONオブジェクトは技術的にRFC 4627に準拠していますが、JSONオブジェクトはすべての JSON値(文字列、null、数値を含む)を受け入れます。

したがってJSON.stringify(5)、を介して適合ブラウザで数値を文字列化できます。これは、RFC4627に準拠している別のパーサーによって拒否されますが、上記の特定の例外はありません。たとえば、Rubyは、オブジェクトと配列のみをrootとして受け入れる1つの例です。一方、PHPは、「スカラー型とNULLもエンコードおよびデコードする」という例外具体的に追加しています。


@amdorra:それが見られる場所をより具体的にすることはできますか?
マット

5
JSONは名詞ではないため、「a JSON」は無意味です。「JSON値」は「JSON値」ですが、パーサーはそのRFCで定義されている「JSONテキスト」を期待することがよくあります。
IMSoP 2013

2
私の悪い私はその後私の答えを削除します
amdorra

1
@jmorenoコメントを明確にしていただけませんか?あなたは言っているtruefalseまたはnull単独の有効なJSONテキストのですか?これは他のほとんどの回答/コメントと矛盾しているので、出典を引用してください。
ローレンスジョンストン

2
@jmoreno:確かにセクション2の引用「JSONテキストはシリアル化されたオブジェクトまたは配列です。」それに反対ですか?JSON Lintは、非配列またはオブジェクトが有効であるとは見なしません。文字列が有効なJSONリテラルであるかどうかについては議論はありません。これは、文字列自体が有効かどうかの問題です。
マット

42

インターネット上には、JSON標準と見なすことができるドキュメントが少なくとも4つあります。参照されているRFCはすべてMIMEタイプを記述していapplication/jsonます。トップレベルの値と、オブジェクトまたは配列以外のものをトップで許可するかどうかについて、それぞれが次のように言う必要があります。

RFC-4627いいえ。

JSONテキストはトークンのシーケンスです。トークンのセットには、6つの構造文字、文字列、数字、および3つのリテラル名が含まれています。

JSONテキストは、シリアル化されたオブジェクトまたは配列です。

JSON-text =オブジェクト/配列

RFC-4627は「提案された標準」ではなく「情報提供」としてマークされ、RFC-7159によって廃止され、RFC-8259によって廃止されることに注意してください。

RFC-8259はい。

JSONテキストはトークンのシーケンスです。トークンのセットには、6つの構造文字、文字列、数字、および3つのリテラル名が含まれています。

JSONテキストはシリアル化された値です。JSONの特定の以前の仕様では、JSONテキストがオブジェクトまたは配列になるように制約されていました。JSONテキストが要求されるオブジェクトまたは配列のみを生成する実装は、すべての実装がこれらを適合JSONテキストとして受け入れるという意味で相互運用可能です。

JSON-text = ws value ws

RFC-8259の日付は2017年12月で、「インターネット標準」とマークされています。

ECMA-262はい。

JSON構文文法は、JSON字句文法で定義されたトークンに関して有効なJSONテキストを定義します。文法の目標シンボルはJSONTextです。

構文JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404はい。

JSONテキストは、JSON値の文法に準拠するUnicodeコードポイントから形成される一連のトークンです。トークンのセットには、6つの構造トークン、文字列、数値、および3つのリテラル名トークンが含まれます。


10

RFC 4627(2014年3月にRFC 7159によって廃止された)の古い定義によれば、これらはすべて有効な「JSON値」でしたが、最後の2つだけが完全な「JSONテキスト」を構成します。

JSONテキストは、シリアル化されたオブジェクトまたは配列です。

使用するパーサーによっては、「JSON値」だけが受け入れられる場合があります。例(「JSON値」と「JSONテキスト」の用語を区別しない):

  • JSON.parse()最近のブラウザーで標準化された関数は、「JSON値」を受け入れます
  • PHP関数json_decodeはバージョン5.2.0で導入され、「JSONテキスト」全体のみを受け入れましたが、バージョン5.2.1では「JSON値」を受け入れるように修正されました
  • このマニュアルページのjson.loadsよると、Python は「JSON値」を受け入れます
  • http://jsonlint.comのバリデータは完全な「JSONテキスト」を期待します
  • Ruby JSONモジュールは完全な「JSONテキスト」のみを受け入れます(少なくともこのマニュアルページのコメントよると)

この区別は、「XMLドキュメント」と「XMLフラグメント」の区別に少し似ていますが、技術的に<foo />は整形式のXMLドキュメントです(として記述した方がよいですが<?xml version="1.0" ?><foo />、コメントで指摘されているように、<?xml宣言は技術的にオプションです) )。


XMLドキュメントはオプションのXML宣言がなくても完全に有効であるため、XMLの比較は不適切な場合があります。w3.org/TR/xml/#sec-well-formed
Gunther

@Guntherああ、そうです。強くお勧めしますが、技術的にはオプションであることを忘れていました。
IMSoP 2013

@Gunther:nitpick:<foo />整形式の XMLドキュメントですが、有効なドキュメントではありません。(ただし、同じことが<?xml version="1.0" ?><foo />。)
ruakh 2013

@ruakh興味深いことに、ここの定義 XMLがDTDに対してのみ「有効」である可能性があることを意味します。つまり、DTDが(XSDやRelaxNGなどのスキーマ定義形式と比較して)実際に作成および宣言されることはほとんどないため、XMLドキュメントはほとんどありません。 。参照しなくても外部スキーマに対して有効である場合、特定のスキーマに対して有効である<foo /> 場合とそうでない場合があるので、私はチェックしていましたが、それその標準で述べられていることではありません。
IMSoP 2013

4

ecma仕様は参照に役立つ場合があります。

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

parse関数は、JSONテキスト(JSON形式の文字列)を解析し、ECMAScript値を生成します。JSON形式は、ECMAScriptリテラルの制限された形式です。JSONオブジェクトはECMAScriptオブジェクトとして実現されます。JSON配列はECMAScript配列として実現されます。JSON文字列、数値、ブール値、およびnullは、ECMAScript文字列、数値、ブール値、およびnullとして実現されます。JSONはWhiteSpaceよりも制限された空白文字のセットを使用し、UnicodeコードポイントU + 2028およびU + 2029をエスケープシーケンスを使用せずにJSONStringリテラルに直接表示できます。解析のプロセスは、JSON文法によって制約される11.1.4および11.1.5に似ています。

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
有用なリファレンスですが、これは特定のJSONパーサー(ECMAScript標準で定義されているもの)の仕様であり、形式自体の仕様ではありません。json.orgは、JSONは「完全に言語に依存しない」と明示しているため、正しいパーサーはありません。
IMSoP 2013

1
JavaScript / ECMASciptはJSONのインスピレーションであり、JSONのユーザーですが、その「ホーム」ではありません。JSONは、ECMAScript(のすべての以前のバージョン)のオブジェクトリテラル表記から派生したものですが、同一ではありません。JSON.parse関数は、クロックフォードの文法とRFCに基づいてのECMAScript標準のそれ以降のバージョンに追加されました。
IMSoP 2013

4
あなたがするべきことJSON.parse("\"string\"");
ericbn 2017

4

JSONはJavaScript Object Notationの略です。JavaScriptオブジェクトのみ{}[]定義します。他の例は値リテラルです。JavaScriptには、これらの値を操作するためのオブジェクトタイプがありますが、式"string"はリテラル値のソースコード表現であり、オブジェクトではありません。

JSONはJavaScriptではないことに注意してください。データを表す表記です。非常にシンプルで限定的な構造です。JSONデータは{},:[]文字を使用して構造化されます。その構造内ではリテラル値のみを使用できます。

サーバーがオブジェクトの説明またはリテラル値のいずれかで応答することは完全に有効です。すべてのJSONパーサーは、リテラル値だけを処理するために処理する必要がありますが、値は1つだけです。JSONは一度に1つのオブジェクトしか表現できません。したがって、サーバーが複数の値を返すには、オブジェクトまたは配列として構造化する必要があります。


1
この方向から答えに近づくと、明確ではありません。名前の由来は標準の詳細に関係なく、JavaScriptで使用可能なタイプはJSONのタイプのインスピレーションになるかもしれませんが、要件はありません。それらが一致すること。json.orgの紹介により、「JSONは完全に言語に依存しないテキスト形式です」
IMSoP 2013

@IMSoP完全に同意します。JavaScriptの型とJSONを混在させましたが、これは正しくありません。回答を更新します。
Reactgular 2013

2

はい、はい、はい、はい、そしてはい。それらはすべて有効なJSON値リテラルです。

ただし、公式のRFC 4627には次のように記載されています。

JSONテキストは、シリアル化されたオブジェクトまたは配列です。

したがって、「ファイル」全体は、最も外側の構造としてのオブジェクトまたは配列で構成する必要があります。もちろん、空にすることもできます。しかし、多くのJSONパーサーはプリミティブ値も入力として受け入れます。


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

だからあなたの答えは"{}"、空のオブジェクトを表すものです。


FWIW、Chromeでは、これはundefined「{}」ではなくを与えます`
Matt

-2

json.orgページにある鉄道図に従ってください。[]および{}は、可能な最小の有効なJSONオブジェクトです。したがって、答えは[]と{}です。


3
FSMではなく、文法です。また、どのプロダクションが開始ルールであるかを示しているようには見えません。開始ルールがあった場合arrayobject、あなたは右のだろうが、それは予想するのが妥当だvalue開始します。

私にはかなり簡単に見えますが。ダグラス・クロックフォードはそれを彼らと呼んでおり、私たちは常に左から始めて、右のトラックをたどります。最小のトラックは最小限の有効なJSONを提供します。
Hrishi 2013

2
それは私が反対している特定の文法規則のあなたの解釈ではありません、それはあなたが2つの規則を選び、1つが他のものからではなくそれらからのみ始めることができると仮定するということです。and ルールのvalues代わりに(またはそれに加えて)ルールを見る場合、スタンドアロンの数値と文字列は有効なJSONドキュメントです。arrayobject

-1。まず、@ delnanが指摘しているように、json.orgの図には、完全なJSONテキストがオブジェクトまたは配列である必要があることは示されていません。json.orgに基づいてではなく、これら2つを任意に選択しました。第2に、用語をめくる:[]、これまで問題について意見があったすべての仕様での有効なJSONテキストは、JSONオブジェクトではないため、「有効なJSONオブジェクト」ではありません。JSONの「オブジェクト」は特に{}表記法を指します。JSON配列はJSONオブジェクトではありません。
Mark Amery
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.