Minimum geçerli JSON nedir?


174

Http://json.org/ JSON açıklamasını dikkatlice okudum ama basit sorunun cevabını bildiğimden emin değilim. Mümkün olan minimum geçerli JSON hangi dizelerdir?

  • "string" dize geçerli JSON nedir?
  • 42 sayı geçerli JSON nedir?
  • true boolean değeri geçerli bir JSON mu?
  • {} boş nesne geçerli bir JSON mu?
  • [] boş dizi geçerli bir JSON mu?

12
Jsonlint.com'da test edildiğinde , son ikisi geçerlidir, diğerleri geçerli değildir.
ironcito

1
bazı JSON ayrıştırıcıları bir dizi veya nesne bekler. Sadece bir sayı ya da bir dize hakkında şikayet ediyorlar.
akonsu

3
Şu an itibariyle, bunlar geçerli
Brian Colavito


kısa cevap - {}
Tukaram Bhosale

Yanıtlar:


156

Yazma sırasında, JSON yalnızca RFC4627'de açıklanmıştır . JSON metnini ("2" nin başında) serileştirilmiş bir nesne veya dizi olarak tanımlar.

Bu , ayrıştırıcılarda ve dizgi oluşturucularda bu standarda bağlı olan yalnızca {} ve []geçerli, eksiksiz JSON dizeleri anlamına gelir .

Bununla birlikte , ECMA-404'ün tanıtımı bunu değiştirir ve güncellenmiş tavsiyeler burada okunabilir . Ayrıca konuyla ilgili bir blog yazısı da yazdım .


Ancak konuyu daha da karıştırmak için , web tarayıcılarında bulunan JSONnesne (örn. JSON.parse()Ve JSON.stringify()) ES5'te standartlaştırılmıştır ve bu, kabul edilebilir JSON metinlerini şu şekilde açıkça tanımlar:

Bu spesifikasyonda kullanılan JSON değişim formatı, tam olarak RFC 4627 tarafından iki istisna dışında açıklanmıştır:

  • ECMAScript JSON dilbilgisinin en üst düzey JSONText üretimi, RFC 4627 tarafından belirtilen bir JSONObject veya JSONArray olmakla sınırlı olmak yerine herhangi bir JSONValue'dan oluşabilir.

  • Kesik

Bu , JSON nesnesi teknik olarak RFC 4627'ye uysa bile , tüm JSON değerlerinin (dizeler, boş değerler ve sayılar dahil) JSON nesnesi tarafından kabul edildiği anlamına gelir .

Bu nedenle, uygun bir tarayıcıdaki bir sayıyı, JSON.stringify(5)RFC4627'ye uyan ancak yukarıda listelenen özel bir istisna içermeyen başka bir ayrıştırıcı tarafından reddedilebileceğini unutmayın. Örneğin Ruby, yalnızca kök olarak nesneleri ve dizileri kabul eden bir örnek gibi görünmektedir . PHP ise "skaler türleri ve NULL kodlayacağı ve deşifre edeceği" özel durumunu ekler .


@amdorra: Bunu gördüğünüz yerde daha spesifik olabilir misiniz?
Matt

5
JSON bir isim değildir, bu yüzden "bir JSON" anlamsızdır. Herhangi bir "JSON değeri" bir "JSON değeri" dir, ancak ayrıştırıcılar genellikle bu RFC'de tanımlandığı gibi bir "JSON metni" bekler.
IMSoP

2
benim kötü o zaman cevabımı silerim
amdorra

1
@jmoreno Yorumunuzu açıklığa kavuşturabilir misiniz? Eğer söylüyorsun true, falseya nulltek başına geçerli bir JSON metindir? Buradaki diğer cevapların / yorumların çoğuyla çeliştiği için lütfen bir kaynak gösterebilir misiniz?
Lawrence Johnston

2
@jmoreno: Kesinlikle bölüm 2'den alıntı "JSON metni serileştirilmiş bir nesne veya dizidir." Buna karşıt mı? JSON Lint, dizi veya nesnenin geçerli olmadığını da düşünmez. Bir dizenin geçerli bir JSON değişmezi olup olmadığı konusunda bir tartışma yoktur; bir dizenin kendisinin geçerli olup olmadığı budur.
Matt

42

İnternette JSON standartları olarak kabul edilebilecek en az dört belge vardır. Referans verilen tüm RFC'ler mime tipini tanımlar application/json. Her birinin en üst düzey değerler ve üstte bir nesne veya dizi dışında herhangi bir şeye izin verilip verilmediği hakkında söyleyecekleri:

RFC-4627 : Hayır.

JSON metni bir dizi dizgidir. Simge seti altı yapısal karakter, dize, sayı ve üç değişmez ad içerir.

JSON metni serileştirilmiş bir nesne veya dizidir.

JSON-text = nesne / dizi

RFC-4627'nin "önerilen standart" yerine "bilgilendirici" olarak işaretlendiğine ve RFC-7159 tarafından kullanılmadığına ve bunun RFC-8259 tarafından kullanılmadığına dikkat edin.

RFC-8259 : Evet.

JSON metni bir dizi dizgidir. Simge seti altı yapısal karakter, dize, sayı ve üç değişmez ad içerir.

JSON metni serileştirilmiş bir değerdir. Önceki JSON spesifikasyonlarının bir JSON metnini bir nesne veya dizi olarak sınırladığını unutmayın. Yalnızca bir JSON metninin çağrıldığı nesneleri veya dizileri oluşturan uygulamalar, tüm uygulamaların bunları uygun JSON metinleri olarak kabul etmesi açısından birlikte çalışabilir.

JSON-text = ws değeri ws

RFC-8259 Aralık 2017 tarihlidir ve "İNTERNET STANDARDI" olarak işaretlenmiştir.

ECMA-262 : Evet.

JSON Sözdizimsel Dilbilgisi, JSON sözcüksel dilbilgisi tarafından tanımlanan belirteçler için geçerli bir JSON metni tanımlar. Dilbilgisinin hedef sembolü JSONText'tir.

Sözdizimi JSONText:

JSONValue

Değer:

JSONNullLiteral

JSONBooleanLiteral

JSONObject nesnesi

JSONArray

JSONString

JSONNumber

ECMA-404 : Evet.

JSON metni, Unicode kod noktalarından oluşturulan ve JSON değeri dilbilgisine uyan belirteç dizisidir. Belirteçler kümesi altı yapısal belirteç, dize, sayı ve üç değişmez ad belirteci içerir.


10

RFC 4627'deki (RFC 7159 tarafından Mart 2014'te kullanılmayan) eski tanıma göre , bunların tümü geçerli "JSON değerleri" idi, ancak yalnızca son ikisi tam bir "JSON metni" oluşturacaktı:

JSON metni serileştirilmiş bir nesne veya dizidir.

Kullanılan ayrıştırıcıya bağlı olarak, yalnız "JSON değerleri" yine de kabul edilebilir. Örneğin ("JSON metni" terminolojisine karşı "JSON değerine" yapışmak):

  • JSON.parse()modern tarayıcılarda standart hale getirilen işlev herhangi bir "JSON değeri" ni kabul eder
  • PHP işlevi json_decode5.2.0 sürümünde yalnızca bütün bir "JSON metni" kabul edilerek tanıtıldı, ancak 5.2.1 sürümünde herhangi bir "JSON değeri" kabul edilecek şekilde değiştirildi
  • Python's , bu kılavuz sayfasındakijson.loads örneklere göre herhangi bir "JSON değerini" kabul eder
  • http://jsonlint.com adresindeki doğrulayıcı tam bir "JSON metni" bekliyor
  • Ruby JSON modülü yalnızca tam bir "JSON metni" kabul eder (en azından bu kılavuz sayfasındaki yorumlara göre )

Teknik <foo />olarak iyi biçimlendirilmiş bir XML belgesi olmasına rağmen, ayrım "XML belgesi" ile "XML parçası" arasındaki farka benzer (açıklamalarda belirtildiği gibi daha iyi yazılır <?xml version="1.0" ?><foo />, <?xmlaçıklama teknik olarak isteğe bağlıdır) ).


XML karşılaştırması uygunsuz olabilir, çünkü bir XML belgesi isteğe bağlı XML bildirimi olmadan tamamen geçerlidir. W3.org/TR/xml/#sec-well-formed
Gunther

@Gunther Ah, evet, teknik olarak isteğe bağlı olduğunu unutmuştum, ancak oldukça teşvik ediliyor.
IMSoP

@Gunther: Bir nitpick: <foo />Bir olan iyi biçimli XML belgesi, ancak bir geçerli bir. (Ama aynı şey doğrudur <?xml version="1.0" ?><foo />.)
ruakh

@ruakh İlginç bir şekilde, buradaki tanım , XML'in bir DTD'ye karşı yalnızca "geçerli" olabileceğini, yani DTD'lerin çok nadiren pratikte yazıldığını ve bildirildiğinden (XSD veya RelaxNG gibi şema tanımlama formatlarıyla karşılaştırıldığında) çok az XML belgesinin olduğu anlamına gelir. . Kontrol ediyordum, çünkü harici bir şemaya karşı geçerli olmadan, referans vermeden geçerli <foo /> olabilirseniz , o zaman belirli bir şemaya karşı geçerli olabilir veya olmayabilir , ancak bu standart durumlar böyle değildir.
IMSoP

4

Ekma spesifikasyonu referans için yararlı olabilir:

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

Ayrıştırma işlevi bir JSON metnini (JSON biçimli Dize) ayrıştırır ve bir ECMAScript değeri üretir. JSON biçimi, ECMAScript değişmezinin sınırlı bir biçimidir. JSON nesneleri ECMAScript nesneleri olarak gerçekleştirilir. JSON dizileri ECMAScript dizileri olarak gerçekleştirilir. JSON karakter dizileri, sayılar, booleanlar ve null, ECMAScript Dizeler, Sayılar, Boole ve null olarak gerçekleştirilir. JSON, WhiteSpace'ten daha sınırlı sayıda beyaz boşluk karakteri kullanır ve Unicode kod noktaları U + 2028 ve U + 2029'un bir kaçış dizisi kullanmadan JSONString değişmez değerlerinde doğrudan görünmesini sağlar. Ayrıştırma işlemi, JSON dilbilgisi tarafından kısıtlandığı şekliyle 11.1.4 ve 11.1.5'e benzer.

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
Yararlı bir referans olsa da, biçimin kendisi için değil, belirli bir JSON ayrıştırıcısının (ECMAScript standardında tanımlanan) belirtimi budur. json.org, JSON'un "tamamen dilden bağımsız" olduğunu açıkça belirtmektedir, bu yüzden doğru bir ayrıştırıcı yoktur.
IMSoP

1
JavaScript / ECMAScipt, JSON ve bir kullanıcısı için ilham kaynağıdır, ancak "ana sayfası" değildir. JSON, ECMAScript'in (önceki tüm sürümlerinde) nesne değişmez gösteriminden türetilmiştir, ancak onunla aynı değildir. JSON.parseFonksiyon sonra Crockford en gramer ve RFC dayalı ECMAScript standardının sonraki sürümlerinde eklendi.
IMSoP

4
Yapmanız gerekirJSON.parse("\"string\"");
ericbn

4

JSON, JavaScript Nesne Gösterimi anlamına gelir. Yalnızca {}ve []bir Javascript nesnesi tanımlayın. Diğer örnekler değer değişmezleridir. Javascript'te bu değerlerle çalışmak için nesne türleri vardır, ancak ifade "string"bir nesne değil değişmez değerin kaynak kodu temsilidir.

JSON'un Javascript olmadığını unutmayın. Verileri temsil eden bir gösterimdir. Çok basit ve sınırlı bir yapıya sahiptir. JSON verileri {},:[]karakterler kullanılarak yapılandırılır . Yalnızca bu yapının içindeki değişmez değerleri kullanabilirsiniz.

Bir sunucunun nesne açıklaması veya değişmez değerle yanıt vermesi tamamen geçerlidir. Tüm JSON ayrıştırıcıları yalnızca bir gerçek değeri değil, yalnızca bir değeri işleyebilmelidir. JSON aynı anda yalnızca tek bir nesneyi temsil edebilir. Bu nedenle bir sunucunun birden fazla değer döndürmesi için onu bir nesne veya dizi olarak yapılandırması gerekir.


1
Cevabın bu yönden yaklaşması açıklıktan daha fazla çamurlu olduğunu düşünüyorum: isminin kökeni standardın detaylarını etkilemez ve JavaScript'te mevcut olan türler JSON'daki türler için ilham kaynağı olabilir, ancak gereklilik yoktur onlar maç. Json.org'daki giriş bunu açıkça ortaya koyuyor: "JSON tamamen dilden bağımsız bir metin biçimidir"
IMSoP

@IMSoP Kesinlikle katılıyorum. Javascript türlerini JSON ile karıştırdım ve bu doğru değil. Cevabımı güncelleyeceğim.
Reactgular

2

Evet, evet, evet, evet ve evet. Hepsi geçerli JSON değeri değişmez değerleridir.

Ancak, resmi RFC 4627 şunları belirtmektedir:

JSON metni serileştirilmiş bir nesne veya dizidir.

Bu nedenle, tüm "dosya" en dıştaki yapı olarak bir nesne veya diziden oluşmalıdır, ki bu elbette boş olabilir. Ancak, birçok JSON ayrıştırıcısı girdi için de ilkel değerleri kabul eder.


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

Yani cevabınız "{}"boş bir nesneyi ifade ediyor.


FWIW, Chrome'da bu undefined, "{}" değil , verir
Matt

-2

Sadece json.org sayfasında verilen demiryolu şemalarını takip edin . [] ve {} mümkün olan en düşük geçerli JSON nesneleridir. Cevap [] ve {}.


3
Bu bir FSM değil, bir dilbilgisi. Ve hangi üretimin başlangıç ​​kuralı olduğunu göstermiyor gibi görünüyor. Başlangıç kuralları olsaydı arrayve objectsen doğru olurdu, ama beklemek için makul valuebir başlangıç olmasını.

Yine de bana oldukça basit görünüyor. Douglas Crockford onları çağırıyor ve biz her zaman soldan başlıyor ve sağdaki parçaları takip ediyoruz. En küçük parça minimum geçerli JSON değerini verir.
Hrishi

2
İtiraz ettiğim herhangi bir dilbilgisi kuralını yorumlamanız değil, iki kural seçtiniz ve birinin sadece onlardan başlayabileceğini, başkalarından başlayabileceğini varsayıyorsunuz. Kuralına ve kurallarına values(veya ek olarak) bakarsanız, bağımsız sayılar ve dizeler geçerli bir JSON belgesidir. arrayobject

-1. Birincisi, @delnan'ın işaret ettiği gibi, json.org'daki diyagramlardaki hiçbir şey tam bir JSON metninin bir nesne veya dizi olması gerektiğini göstermez; json.org'daki hiçbir şeye dayanmadan bu ikisini keyfi olarak seçtiniz. İkincisi, terminoloji üzerinde nitpicking: []konuyla ilgili bir fikri olan her spekülasyon altında geçerli bir JSON metni, bir JSON nesnesi olmadığı için "geçerli bir JSON nesnesi" değildir. JSON'daki "Object" özellikle {}gösterime atıfta bulunur ; JSON dizileri JSON nesneleri değildir.
Mark Amery
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.