JSONは「[」で始めることができますか?


178

私がjson.orgで読むことができるものから、すべてのJSON文字列は{(中括弧)で始まり、[文字(角括弧)はJSONの配列要素を表す必要があります。

私はjson4jライブラリを使用し、で始まる入力を取得した[ため、これが有効なJSONであるとは思いませんでした。JSONスキーマを簡単に確認しましたが、JSONファイルがで開始できない[、またはJSONでしか開始できないと記載されていることを実際に見つけることができませんでした{


(どうやら、最も外側のJSONタイプを知る必要がある、設計が不適切なJSONライブラリがいくつかあります。ここで最も簡単な「修正」は、JSON文字列を[]で囲み、それを配列として解析し、最初の配列要素を取得することです。)
Hot Licks

どうやら{ではなく{で始める方が安全なため、有効なJavaScript配列ではないため、CSRF攻撃に使用することはできません。
David Klempfner、2018

回答:


218

JSONは、配列またはオブジェクトのいずれかです。具体的にはjson.orgから:

JSONは2つの構造に基づいて構築されています。

  • 名前と値のペアのコレクション。さまざまな言語では、これはオブジェクト、レコード、構造体、辞書、ハッシュテーブル、キー付きリスト、または連想配列として実現されます。
  • 値の順序付きリスト。ほとんどの言語では、これは
    配列、ベクトル、リスト、またはシーケンスとして実現されます。

次に、2つの構造を次のように説明します。 JSONオブジェクト JSON配列

開始文字と終了文字はそれぞれ中括弧と角括弧であることに注意してください。

編集して
、ここから:http : //www.ietf.org/rfc/rfc4627.txt

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

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

アップデート(2014)

2014年3月の時点で、定義をわずかに変更する新しいJSON RFC(7159)があります(4/5ページを参照)。

RFC 4627による定義は次のとおりです。 JSON-text = object / array

これはRFC 7159で次のように変更されました。 JSON-text = ws value ws

どこにws空白を表し、value次のように定義されています。

JSON値は、オブジェクト、配列、数値、文字列、または次の3つのリテラル名のいずれかである必要があります。

false null true

したがって、質問への答えはまだです。JSONテキストは角括弧(つまり、配列)で始めることができます。ただし、オブジェクトや配列に加えて、数値、文字列、値falsenullまたはにすることもできますtrue

また、これは以前のRFC 4627の引用(強調を追加)から変更されています。

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

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


おかげで、私はその図を何度も見て、どうやらjson4jライブラリに問題があるようです。
ティベリ2011

1
@Tiberiu Hajas:最初に見つけたとき、理解するのに少し時間がかかりました。しかし、JSONのいくつかの例を見て、それらを比較した後、私は本当に彼らがそれをした方法が好きです。json4jについては、おそらくjson4jライブラリの作成者にバグレポートを送信できます。
Richard Marskell-Drackir、2011年

パーティーに遅れそうだ。しかし、RFC 8259で見つけたものによると、JSONテキストは、JSON値の文法に準拠するUnicodeコードポイントから形成された一連のトークンであると述べています。トークンのセットには、6つの構造トークン、文字列、数値、および3つのリテラル名トークンが含まれます。これは合法的なもののように聞こえます:{"1234"}、{true}。しかし、これは何を表していますか?<code> [] </ code>がないため、これは配列ではありません。2つあるため、これもオブジェクトではありません。
ニコラスハンフリー

1
@NicholasHumphrey上記の記述は8259にも適用されます。同じセクション2(JSON文法)でJSON-text(別名JSONドキュメント)は次のように定義されJSON-text = ws value wsます。または、セクション3(値)に従って、false、null、trueの3つのリテラル名のいずれか。あなたの例はこれらの制約を満たさないため、有効なJSONではありません。
Richard Marskell-Drackir

8

解析している文字列が左中括弧([)で始まっている場合はJSONArray.parse、JSONArrayオブジェクトを取得するために使用できget(i)iが0から返された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();
      }
   }
}

次のような出力が生成されました:

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

注:呼び出そJSONObject.parse(books.toString());うとすると、発生したエラーが発生します。

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

1
より単純なコードでは、get呼び出しから返されたオブジェクトでinstanceof JSONArrayとinstanceof JSONObjectを使用して、オブジェクトの解析に使用するクラスを決定する場合があります...
Nathaniel Mills

5

JSON.ORG WEBSITE SAYS ....

https://www.json.org/

サイトは明確に次のように述べています:

JSONは2つの構造に基づいて構築されています。

  1. 名前と値のペアのコレクション。さまざまな言語では、これはオブジェクト、レコード、構造体、辞書、ハッシュテーブル、キー付きリスト、または連想配列として実現されます。

  2. 値の順序付きリスト。ほとんどの言語では、これは配列、ベクトル、リスト、またはシーケンスとして実現されます。

これらは普遍的なデータ構造です。ほとんどすべての最新のプログラミング言語は、何らかの形でそれらをサポートしています。プログラミング言語と互換性のあるデータ形式もこれらの構造に基づいていることは理にかなっています。JSONでは、次の形式を取ります。

OBJECT:

オブジェクトは、名前と値のペアの順不同のセットです。オブジェクトは{(左中括弧)で始まり、}(右中括弧)で終わります。各名前の後に:(コロン)が続き、名前と値のペアは、(カンマ)で区切られます。

{string: value, string: value}

アレイ:

配列は、値の順序付けられたコレクションです。配列は[(左角括弧)で始まり、](右角括弧)で終わります。値は、(コンマ)で区切られます。

[value, value, value ….]

値:

値は、二重引用符で囲まれた文字列、数値、trueまたはfalseまたはnull、またはオブジェクトや配列です。これらの構造はネストすることができます。

ストリング:

文字列は、バックスラッシュエスケープを使用して、二重引用符で囲まれた0個以上のUnicode文字のシーケンスです。文字は単一の文字列として表されます。文字列は、CまたはJavaの文字列によく似ています。

数:

数値は、CまたはJavaの数値と非常によく似ていますが、8進数および16進数の形式が使用されない点が異なります。

ホワイトスペースについて:

空白はトークンのペアの間に挿入できます。いくつかのエンコーディングの詳細を除いて、言語を完全に説明しています。


例で良い。これは、JSONバリデーターの単体テストを書くのに役立ちました。文字列の意味がわかりませんでした(たとえば、二重引用符で囲まれた文字列である必要があります)。
gimlichael

私はそれがどのように混乱する可能性があるのか​​を理解します。この文は、次のように少し簡潔になる可能性があります:「0個以上のUnicode文字のシーケンス...」重要なポイントが見やすくなるようにレイアウトしました。返答が遅れますが、必要に応じてそれが明確になることを願っています。
J.モレノ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.