JSON(Java Script Object Notation)是業(yè)界最為普遍的內(nèi)部數(shù)據(jù)交換的輕量級(jí)協(xié)議榆芦,人機(jī)都方便讀寫。JSON語(yǔ)法非常精練亦鳞,我們從它的BNF范式角度來(lái)學(xué)習(xí)可謂是最快速和最容易的學(xué)習(xí)方法僧界。
JSON包含兩種格式,分別用BNF表示就是:
-
1.name/value對(duì)的object格式
name/value.png
如下數(shù)據(jù)是符合上圖格式要求的:
[root@VM_0_10_centos ~]# cat person.js
{ "name":"Mike", "age":34}
對(duì)照BNF圖很好理解型宝,name/value對(duì)一定出現(xiàn)在一對(duì)大括號(hào)里面八匠,每對(duì)之間用逗號(hào)隔開絮爷。
每個(gè)name/value對(duì)中,name一定是json中的string類型數(shù)據(jù)梨树,也即是我們常用的字符串坑夯,value是我們后面要定義的value類型。name和value之間用冒號(hào)隔開抡四。
很顯然柜蜈,下面例子不符合格式要求:
[root@VM_0_10_centos ~]# cat person_err.js
{ "name":"Mike", "age"}
{ "name":"Mike", }
{ :"Mike", "age":34}
第一個(gè)例子:"age"后面的value沒(méi)有定義。(錯(cuò)誤)
第二個(gè)例子:定義了逗號(hào)指巡,沒(méi)有定義后續(xù)的name/value對(duì)淑履。(錯(cuò)誤)
第三個(gè)例子:第一個(gè)name/value對(duì)的name丟失了。(錯(cuò)誤)
依照BNF圖很容易看出和理解如何保證數(shù)據(jù)符合JSON的格式要求藻雪。
我們要知道秘噪,這里的string和value都還有特殊的格式要求,后面會(huì)介紹和學(xué)習(xí)勉耀。
-
2.value的array格式
value order.png
如下數(shù)據(jù)就是符合value的順序列表格式的格式要求的:
[root@VM_0_10_centos ~]# cat persons.js
[ "Bill" , "Mike" , "John" ]
按照要求指煎,value的array一定包含在一對(duì)方括號(hào)之間,這有限對(duì)的value的列表之間用逗號(hào)隔開便斥。
按照?qǐng)D示至壤,我們很容易理解如下的數(shù)據(jù)格式是不符合語(yǔ)法要求的:
[root@VM_0_10_centos ~]# cat persons_err.js
[ "Bill" , "Mike" , ]
[ , "Mike" , "John" ]
-
3.值value的構(gòu)成定義
value.png
按照?qǐng)D示,我們能迅速明白了如何構(gòu)成JSON中的所謂的值枢纠,第一類值就是字符串像街,第二類是數(shù)字,第三類是object晋渺,第四類是array宅广,第五類和第六類是邏輯運(yùn)算的true和false,最后一類就是null些举。而且在值的前后分別有whitespace跟狱。是不是很容易!
特殊的需要交代下:
- 這里有個(gè)遞歸的引用户魏,object 可以作為value來(lái)使用驶臊。例如:
[root@VM_0_10_centos ~]# cat persons1.js
[ "Manager" , "HR department" , "level20",{ "name":"Mike", "age":34} ]
我們可以簡(jiǎn)單理解為方括號(hào)里面嵌套大括號(hào)。
這里的object 作為了value出行在array中叼丑。
- value構(gòu)成的array也可以作為value再次遞歸出現(xiàn)关翎。例如:
[[ "Manager" , "HR department" , "level20",{ "name":"Mike", "age":34} ],
[ "Senior Manager" , "IT department" , "level30",{ "name":"Bill", "age":50} ]]
我們簡(jiǎn)單理解為方括號(hào)里嵌套方括號(hào)。
怎樣的值是字符串鸠信?怎樣的值是數(shù)字纵寝?我們都通過(guò)圖示來(lái)學(xué)習(xí)和掌握。
-
4.whitespace 的構(gòu)成定義
image.png
我們看圖識(shí)空白星立,是不是很容易的感覺(jué)爽茴,所以我們明白了JSON中的whitespace可以是真的什么都沒(méi)有葬凳,也可以是若干的空格符、回車符室奏、換行符火焰、制表符構(gòu)成。
[root@VM_0_10_centos ~]# cat persons1.js
[ "Bill"
, "Mike" , "John"
]
所以上面這個(gè)例子就是一個(gè)語(yǔ)法完全正確的JSON值的表示胧沫。雖然看起來(lái)七零八落的昌简。
-
5.string的定義
JSON中最復(fù)雜的數(shù)據(jù)類型就是string了∪拊梗看看下圖纯赎,是不是比前面的BNF圖都復(fù)雜?
string.png
string要么是一對(duì)空的雙引號(hào)南蹂,要么就是除去一下幾個(gè)特殊符號(hào)的任意字符串,unicode一并支持犬金。
我們要首先認(rèn)識(shí)這幾個(gè)特殊字符符號(hào):
第一個(gè)就是雙引號(hào):雙引號(hào)本身構(gòu)成了string格式定義的一部分,要表達(dá)string中的雙引號(hào)碎紊,要用反斜線轉(zhuǎn)義表達(dá)佑附。
第二個(gè)就是反斜線:反斜線的有特殊的轉(zhuǎn)義的作用樊诺。
其他幾個(gè)特殊的控制符號(hào)必須以反斜線開頭轉(zhuǎn)義使用仗考。
string中的雙引號(hào):\"
string中的斜線:\/
string中的反斜線:\\
string中的回車:\r
string中的換行:\n
string中的換頁(yè):\f
string中的制表符:\t
string中的unicode字符:\u
前面的都很好理解了,最后一個(gè)我們舉例說(shuō)明下:
[root@VM_0_10_centos ~]# cat string.js
{ "name":"\u8d3a", "age":34}
這個(gè)\u8d3a實(shí)際表示的是一個(gè)漢字"賀"。
學(xué)習(xí)完string,其他就是小菜了词爬。
-
6 number的定義
number.png
這個(gè)圖看起來(lái)像個(gè)迷宮秃嗜,實(shí)際只要我們明白了數(shù)字的組成部分,就很容易了顿膨。
任何一個(gè)數(shù)锅锨,可以分成整數(shù)部分和小數(shù)部分,如果數(shù)很大恋沃,可以加上指數(shù)表達(dá)式必搞。
整數(shù)部分的數(shù)字構(gòu)成也很好理解,看看下圖囊咏。
是不是我們常見(jiàn)的數(shù)字的整數(shù)部分就是符合這樣的規(guī)律的恕洲。
[root@VM_0_10_centos ~]# cat numbers.js
12345
-345
9876
111111
0.2222
23.e3
111.e-10
98.e+4
-345:負(fù)數(shù),一定有個(gè)負(fù)號(hào)在最左端梅割。
0.2222:純小數(shù)霜第,最左邊整數(shù)部分是0。
9876:最左端是1-9中的任意一個(gè)數(shù)户辞,后面是0-9任意數(shù)的任意組合泌类。
緊接著是小數(shù)部分的定義。如圖底燎。
0.2222:小數(shù)點(diǎn)后面刃榨,0-9任意數(shù)的任意組合弹砚,構(gòu)成小數(shù)部分。
最后一個(gè)部分的定義是指數(shù)的定義喇澡。如圖迅栅。
23.e3:e(E)是指數(shù)部分的開始,e后面是符號(hào)位晴玖,然后后面是0-9的任意組合读存。
111.e-10:負(fù)指數(shù)必須要有負(fù)號(hào)。負(fù)號(hào)后面是0-9的任意組合呕屎。
98.e+4:正指數(shù)中让簿,正號(hào)是可選的。
好了秀睛,整個(gè)JSON就學(xué)習(xí)完了尔当,真正復(fù)雜的地方就是value定義的遞歸使用。我們使用一個(gè)稍微復(fù)雜的JSON數(shù)據(jù)來(lái)復(fù)習(xí)一下本篇的學(xué)習(xí)內(nèi)容蹂安。
[root@VM_0_10_centos ~]# cat test_schema.js
{
"type": "object",
"properties": {
"first_name": { "type": "string" },
"last_name": { "type": "string" },
"age": { "type": "integer" },
"club": {
"type": "object",
"properties": {
"name": { "type": "string" },
"founded": { "type": "integer" }
},
"required": ["name"]
}
},
"required": ["first_name", "last_name", "age", "club"]
}
整個(gè)是一個(gè)object椭迎,該object由3對(duì)name/value對(duì)構(gòu)成。
第一對(duì)name/value是"type": "object"田盈,很好理解了畜号。
第二對(duì)name/value的value不是簡(jiǎn)單的string或者number,它是另一個(gè)object允瞧。這個(gè)object由5對(duì)name/value對(duì)構(gòu)成简软。這個(gè)object的前面4對(duì)name/value的value又都是另外的object,最后一對(duì)的value是個(gè)array述暂。
第三對(duì)name/value的value是由4個(gè)value構(gòu)成的array痹升。
總體分析還是比較簡(jiǎn)單的。通過(guò)上面的學(xué)習(xí)畦韭,我們對(duì)JSON的語(yǔ)法格式就有了一個(gè)比較深入的了解和學(xué)習(xí)疼蛾,對(duì)常見(jiàn)的JSON數(shù)據(jù)格式,可以做到心中有數(shù)了艺配。