Can JSON start with "["?

From what I can read on json.org, all JSON strings should start with { (curly brace), and [ characters (square brackets) represent an array element in JSON.

I use the json4j library, and I got an input that starts with [, so I didn't think this was valid JSON. I looked briefly at the JSON schema, but I couldn't really find it stated that a JSON file cannot start with [, or that it can only start with {.


Solution 1:

JSON can be either an array or an object. Specifically off of json.org:

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an
    array, vector, list, or sequence.

It then goes on to describe the two structures as: A JSON objectA JSON array

Note that the starting and ending characters are curly brackets and square brackets respectively.

Edit
And from here: http://www.ietf.org/rfc/rfc4627.txt

A JSON text is a sequence of tokens. The set of tokens includes six structural characters, strings, numbers, and three literal names.

A JSON text is a serialized object or array.

Update (2014)

As of March 2014, there is a new JSON RFC (7159) that modifies the definition slightly (see pages 4/5).

The definition per RFC 4627 was: JSON-text = object / array

This has been changed in RFC 7159 to: JSON-text = ws value ws

Where ws represents whitespace and value is defined as follows:

A JSON value MUST be an object, array, number, or string, or one of the following three literal names:

false null true

So, the answer to the question is still yes, JSON text can start with a square bracket (i.e. an array). But in addition to objects and arrays, it can now also be a number, string or the values false, null or true.

Also, this has changed from my previous RFC 4627 quote (emphasis added):

A JSON text is a sequence of tokens. The set of tokens includes six structural characters, strings, numbers, and three literal names.

A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array. Implementations that generate only objects or arrays where a JSON text is called for will be interoperable in the sense that all implementations will accept these as conforming JSON texts.

Solution 2:

If the string you are parsing begins with a left brace ([) you can use JSONArray.parse to get back a JSONArray object and then you can use get(i) where i is an index from 0 through the returned JSONArray's 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();
      }
   }
}

Which produced output like:

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

Note: if you attempted to call JSONObject.parse(books.toString()); you would get the error you encountered:

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

Solution 3:

JSON.ORG WEBSITE SAYS ....

https://www.json.org/

The site clearly states the following:

JSON is built on two structures:

  1. A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

  2. An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures. In JSON, they take on these forms:

OBJECT:

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

{string: value, string: value}

ARRAY:

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

[value, value, value ….]

VALUE:

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

STRING:

A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

NUMBER:

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

ABOUT WHITESPACE:

Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.