Apa JSON yang valid minimum?

174

Saya sudah hati-hati membaca deskripsi JSON http://json.org/ tapi saya tidak yakin saya tahu jawaban atas pertanyaan sederhana. Apa string minimum JSON valid yang mungkin?

  • "string" apakah string JSON itu valid?
  • 42 apakah angka sederhana itu valid JSON?
  • true Apakah nilai boolean JSON yang valid?
  • {} Apakah objek kosong JSON yang valid?
  • [] Apakah array kosong JSON yang valid?
bessarabov
sumber
12
Pengujian di jsonlint.com , dua yang terakhir valid, yang lain tidak.
ironcito
1
beberapa parser JSON mengharapkan array atau objek. Mereka mengeluh hanya tentang angka, atau string.
akonsu
3
Sampai sekarang, itu valid
Brian Colavito
Kemungkinan rangkap dari Apakah string sederhana ini dianggap JSON valid?
ThaJay
jawaban singkat - {}
Tukaram Bhosale

Jawaban:

156

Pada saat penulisan, JSON hanya dijelaskan dalam RFC4627 . Ini menjelaskan (pada awal "2") teks JSON sebagai objek atau larik berseri.

Ini berarti bahwa hanya {} dan []valid, string JSON lengkap dalam parser dan stringifiers yang mematuhi standar itu.

Namun , pengenalan perubahan ECMA-404 itu, dan saran yang diperbarui dapat dibaca di sini . Saya juga menulis posting blog tentang masalah ini.


Untuk membingungkan masalah ini lebih lanjut, JSONobjek (misalnya JSON.parse()dan JSON.stringify()) yang tersedia di browser web distandarisasi dalam ES5 , dan yang dengan jelas mendefinisikan teks JSON yang dapat diterima seperti:

Format pertukaran JSON yang digunakan dalam spesifikasi ini persis seperti yang dijelaskan oleh RFC 4627 dengan dua pengecualian:

  • Produksi JSONTeks tingkat atas dari tata bahasa ECMAScript JSON dapat terdiri dari JSONValue apa pun alih-alih dibatasi menjadi JSONObject atau JSONArray seperti yang ditentukan oleh RFC 4627.

  • terpotong

Ini berarti bahwa semua nilai JSON (termasuk string, nulls dan angka) diterima oleh objek JSON, meskipun objek JSON secara teknis mematuhi RFC 4627.

Perhatikan bahwa karena itu Anda dapat merangkai angka di browser yang sesuai melalui JSON.stringify(5), yang akan ditolak oleh parser lain yang mematuhi RFC4627, tetapi yang tidak memiliki pengecualian khusus tercantum di atas. Ruby, misalnya, tampaknya merupakan salah satu contoh yang hanya menerima objek dan array sebagai root . PHP, di sisi lain, secara khusus menambahkan pengecualian bahwa "itu juga akan menyandikan dan mendekode jenis skalar dan NULL".

Mat
sumber
@amdorra: Bisakah Anda lebih spesifik di mana Anda melihatnya?
Matt
5
JSON bukan kata benda, jadi "JSON" tidak ada artinya. "Nilai JSON" apa pun adalah "nilai JSON", tetapi pengurai sering mengharapkan "teks JSON" sebagaimana didefinisikan dalam RFC itu.
IMSoP
2
buruk saya, saya akan menghapus jawaban saya kemudian
amdorra
1
@ jmoreno Bisakah Anda menjelaskan komentar Anda? Apakah Anda mengatakan true,, falseatau nullsendirian adalah teks JSON yang valid? Bisakah Anda mengutip sumber, karena ini bertentangan dengan sebagian besar jawaban / komentar lain di sini?
Lawrence Johnston
2
@ jmoreno: Tentunya kutipan dari bagian 2 "Sebuah teks JSON adalah objek atau array serial." Menentang itu? JSON Lint juga tidak menganggap non-array atau objek valid. Tidak ada perdebatan tentang apakah string adalah literal JSON yang valid; ini selesai apakah string dengan sendirinya valid.
Matt
42

Setidaknya ada empat dokumen yang dapat dianggap standar JSON di Internet. RFC yang dirujuk semuanya menggambarkan tipe mime application/json. Berikut adalah apa yang masing-masing katakan tentang nilai-nilai tingkat atas, dan apakah sesuatu selain objek atau array diperbolehkan di atas:

RFC-4627 : Tidak.

Teks JSON adalah urutan token. Set token mencakup enam karakter struktural, string, angka, dan tiga nama literal.

Teks JSON adalah objek atau larik berseri.

JSON-text = objek / array

Perhatikan bahwa RFC-4627 ditandai "informasi" sebagai lawan dari "standar yang diusulkan", dan bahwa itu usang oleh RFC-7159 , yang pada gilirannya usang oleh RFC-8259.

RFC-8259 : Ya.

Teks JSON adalah urutan token. Set token mencakup enam karakter struktural, string, angka, dan tiga nama literal.

Teks JSON adalah nilai berseri. Perhatikan bahwa spesifikasi JSON tertentu sebelumnya membatasi teks JSON menjadi objek atau array. Implementasi yang hanya menghasilkan objek atau array di mana teks JSON dipanggil akan dapat dioperasikan dalam arti bahwa semua implementasi akan menerima ini sebagai teks JSON yang sesuai.

JSON-text = ws value ws

RFC-8259 bertanggal Desember 2017 dan ditandai "STANDAR INTERNET".

ECMA-262 : Ya.

Tata Bahasa Sintaks JSON mendefinisikan teks JSON yang valid dalam hal token yang ditentukan oleh tata bahasa leksikal JSON. Simbol tujuan tata bahasa adalah JSONText.

Sintaks JSONTeks:

Nilai JSON

Nilai JSON:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : Ya.

Teks JSON adalah urutan token yang dibentuk dari titik kode Unicode yang sesuai dengan tata bahasa nilai JSON. Set token mencakup enam token struktural, string, angka, dan tiga token nama literal.

Johann
sumber
10

Menurut definisi lama dalam RFC 4627 (yang sudah usang pada bulan Maret 2014 oleh RFC 7159), semua itu adalah "nilai JSON" yang valid, tetapi hanya dua yang terakhir yang merupakan "teks JSON" lengkap:

Teks JSON adalah objek atau larik berseri.

Bergantung pada parser yang digunakan, "JSON values" yang sendirian mungkin dapat diterima. Misalnya (menempel pada terminologi "nilai JSON" vs "teks JSON"):

  • yang JSON.parse()fungsi sekarang standar di browser modern menerima setiap "nilai JSON"
  • fungsi PHP json_decodediperkenalkan dalam versi 5.2.0 hanya menerima keseluruhan "teks JSON", tetapi diubah untuk menerima "nilai JSON" apa pun di versi 5.2.1
  • Python json.loadsmenerima "nilai JSON" apa pun sesuai dengan contoh di halaman manual ini
  • validator di http://jsonlint.com mengharapkan "teks JSON" lengkap
  • modul Ruby JSON hanya akan menerima "teks JSON" lengkap (setidaknya sesuai dengan komentar di halaman manual ini )

Perbedaannya sedikit seperti perbedaan antara "dokumen XML" dan "fragmen XML", meskipun secara teknis <foo />dokumen XML yang terbentuk dengan baik (akan lebih baik ditulis seperti <?xml version="1.0" ?><foo />, tetapi seperti yang ditunjukkan dalam komentar, <?xmldeklarasi secara teknis opsional ).

IMSoP
sumber
Perbandingan XML mungkin tidak sesuai, karena dokumen XML sepenuhnya sah tanpa deklarasi XML opsional. Lihat rekomendasi XML di w3.org/TR/xml/#sec-well-formed
Gunther
@ Gunther Ah, ya, saya lupa bahwa secara teknis opsional, meskipun sangat dianjurkan.
IMSoP
@Gunther: Sebuah nitpick: <foo />adalah well-formed dokumen XML, tapi tidak valid satu. (Tapi hal yang sama berlaku untuk <?xml version="1.0" ?><foo />.)
ruakh
@ruakh Menariknya, definisi di sini menyiratkan XML hanya bisa "valid" terhadap DTD, artinya sangat sedikit dokumen XML, karena DTD sangat jarang ditulis dan dideklarasikan dalam praktik (dibandingkan dengan format definisi skema seperti XSD atau RelaxNG) . Saya sedang memeriksa, karena jika Anda bisa valid terhadap skema eksternal, tanpa mereferensikannya, maka <foo /> mungkin atau mungkin tidak valid terhadap skema tertentu , tetapi bukan itu yang dinyatakan oleh standar itu.
IMSoP
4

Spesifikasi ecma mungkin berguna untuk referensi:

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

Fungsi parse mem-parsing teks JSON (String berformat JSON) dan menghasilkan nilai skrip ECMAS. Format JSON adalah bentuk terbatas dari ECMAScript literal. Objek JSON direalisasikan sebagai objek ECMAScript. Array JSON direalisasikan sebagai array ECMAScript. String JSON, angka, boolean, dan null direalisasikan sebagai String ECMAScript, Bilangan, Boolean, dan nol. JSON menggunakan serangkaian karakter spasi putih yang lebih terbatas daripada WhiteSpace dan memungkinkan titik kode Unicode U + 2028 dan U + 2029 untuk langsung muncul dalam literal JSONString tanpa menggunakan urutan pelarian. Proses parsing mirip dengan 11.1.4 dan 11.1.5 seperti yang dibatasi oleh tata bahasa JSON.

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.
sumber
4
Sementara referensi yang bermanfaat, itu adalah spesifikasi parser JSON tertentu (yang didefinisikan dalam standar ECMAScript) bukan untuk format itu sendiri. json.org secara eksplisit menyatakan bahwa JSON adalah "bahasa sepenuhnya independen", jadi tidak ada satu pengurai yang benar.
IMSoP
1
JavaScript / ECMAScipt adalah inspirasi untuk JSON, dan pengguna, tetapi bukan "rumah" untuknya. JSON diturunkan dari notasi objek literal dalam (semua versi sebelumnya) ECMAScript, tetapi tidak identik dengan itu. The JSON.parseFungsi kemudian ditambahkan ke versi standar ECMAScript berdasarkan tata bahasa Crockford dan RFC.
IMSoP
4
Anda harus melakukanJSON.parse("\"string\"");
ericbn
4

JSON adalah singkatan dari JavaScript Object Notation. Hanya {}dan []tentukan objek Javascript. Contoh lainnya adalah nilai literal. Ada tipe objek dalam Javascript untuk bekerja dengan nilai-nilai itu, tetapi ekspresi "string"adalah representasi kode sumber dari nilai literal dan bukan objek.

Perlu diingat bahwa JSON bukan Javascript. Ini adalah notasi yang mewakili data. Ini memiliki struktur yang sangat sederhana dan terbatas. Data JSON disusun menggunakan {},:[]karakter. Anda hanya bisa menggunakan nilai literal di dalam struktur itu.

Ini sangat valid untuk server untuk merespons dengan deskripsi objek atau nilai literal. Semua parser JSON harus ditangani untuk menangani hanya nilai literal, tetapi hanya satu nilai. JSON hanya bisa mewakili satu objek pada satu waktu. Jadi agar server mengembalikan lebih dari satu nilai, ia harus menyusunnya sebagai objek atau array.

Reactgular
sumber
1
Saya pikir mendekati jawaban dari arah ini berlumpur lebih dari yang menjelaskan: asal usul nama tidak ada hubungannya dengan detail standar, dan jenis yang tersedia di JavaScript mungkin menjadi inspirasi untuk jenis-jenis di JSON, tetapi tidak ada persyaratan bahwa mereka cocok. Pendahuluan di json.org memperjelas: "JSON adalah format teks yang sepenuhnya bebas bahasa"
IMSoP
@ IMSoP Saya sepenuhnya setuju. Saya mencampur tipe Javascript dengan JSON dan itu tidak benar. Saya akan memperbarui jawaban saya.
Reactgular
2

Ya, ya, ya, ya, dan ya. Semuanya adalah literal nilai JSON yang valid.

Namun, RFC 4627 resmi menyatakan:

Teks JSON adalah objek atau larik berseri.

Jadi seluruh "file" harus terdiri dari objek atau array sebagai struktur terluar, yang tentu saja bisa kosong. Namun, banyak parser JSON menerima nilai primitif juga untuk input.

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

Jadi jawaban Anda adalah "{}"yang menunjukkan objek kosong.

Jani Hyytiäinen
sumber
FWIW, Di Chrome, ini memberi undefined, bukan "{}" `
Matt
-2

Cukup ikuti diagram rel yang diberikan di halaman json.org . [] dan {} adalah objek JSON valid minimum yang mungkin. Jadi jawabannya adalah [] dan {}.

Hrishi
sumber
3
Itu bukan FSM, itu tata bahasa. Dan sepertinya tidak mengindikasikan produksi mana yang merupakan aturan awal. Jika aturan awal adalah arraydan objectAnda akan benar, tetapi masuk akal untuk mengharapkan valuemenjadi awal.
Terlihat cukup mudah bagiku. Douglas Crockford menyebut mereka demikian dan kami selalu mulai dari kiri dan mengikuti jejak ke kanan. Track terkecil memberikan JSON valid minimal.
Hrishi
2
Ini bukan interpretasi Anda tentang aturan tata bahasa tertentu yang saya keberatan, itu karena Anda memilih dua aturan dan menganggap satu hanya bisa mulai dari yang, bukan dari yang lain. Jika Anda melihat valuesaturan sebagai gantinya (atau sebagai tambahan) arraydan objectaturan, maka angka dan string mandiri adalah dokumen JSON yang valid.
-1. Pertama, seperti yang ditunjukkan @delnan, tidak ada dalam diagram di json.org yang menyarankan bahwa teks JSON lengkap harus berupa objek atau array; Anda memilih keduanya secara sewenang-wenang, bukan berdasarkan apa pun di json.org. Kedua, memilih terminologi:, []sementara teks JSON yang valid di bawah setiap spesifikasi yang pernah memiliki pendapat tentang masalah ini, bukanlah "objek JSON yang valid", karena itu bukan objek JSON. "Objek" di JSON secara khusus mengacu pada {}notasi; Array JSON bukan objek JSON.
Mark Amery