0
点赞
收藏
分享

微信扫一扫

JSON Schema介绍2

上篇文章主要介绍了JSON Schema的标准、规范、实现(),接下来本文重点介绍JSON Schema的基本概念、使用。

三、快速开始

  • 官网链接:​​http://json-schema.org/learn/​​​  、​​http://json-schema.org/understanding-json-schema/​​
  • json schema在线校验工具:​​https://jsonschemalint.com/​​
  • json schema在线生成功能:​​https://json-schema-inferrer.herokuapp.com/​​​  、​​https://hellosean1025.github.io/json-schema-visual-editor/​​
  • json格式化、压缩、转义在线工具:​​https://www.bejson.com/​​

1、what is schema?

如果您曾经使用过XML Schema,RelaxNG或ASN.1,则可能已经知道什么是schema。要了解JSON Schema,首先要是知道什么事JSON。JSON代表“ JavaScript对象表示法”,一种简单的数据交换格式。它最初是作为万维网的一种表示法,由于大多数网络浏览器中都存在JavaScript,并且JSON基于JavaScript,因此很容易在其中进行支持。js的基本数据类型:

  • object:{ "key1": "value1", "key2": "value2" }
  • array:["a","b"]
  • number:1、1.2
  • string:“string”
  • boolean:true、false
  • null:null

利用这些简单的数据类型,可以表示各种结构化数据。但是,由于其灵活性,导致同一概念可以以多种方式表示。例如:

{
"name": "George Washington",
"birthday": "February 22, 1732",
"address": "Mount Vernon, Virginia, United States"
}

{
"first_name": "George",
"last_name": "Washington",
"birthday": "1732-02-22",
"address": {
"street_address": "3200 Mount Vernon Memorial Highway",
"city": "Mount Vernon",
"state": "Virginia",
"country": "United States"
}
}

以上两种写法表达了同一个信息。记录的设计将在很大程度上取决于其在应用程序中的预期用途,因此这里没有正确或错误的答案。但是,当应用程序说“给我一个人的JSON记录”时,准确知道该记录的组织方式非常重要。例如,我们需要知道需要哪些字段以及如何表示值。这就是JSON Schema的来源

2、基础篇

2.1)特殊的schema:

在JSON Schema中,一个空对象({})是一个有效的schema,它可以兼容所有的json;同样也可以使用true代替空对象来表示匹配任何内容的schema,或者使用false表示不匹配任何内容的schema。例如:

//schema 可以匹配一下所有json
{}

//json
42
"string"
{"a":1}

//同样,true也可以匹配上面所有的json

2.2)声明json schema:

由于JSON Schema本身就是JSON,因此很难分辨出什么是JSON Schema或只是任意JSON块。 $ schema关键字用于声明某些内容为JSON模式。最好将其包括在内,尽管不是必需的。例如:

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
...
}

2.3)keyword:

关键字

描述

$schema

表示该JSON Schema使用的版本规范,非必填,目前最新一版“Draft-07”是2019.09发布的。每个版本的语法可能有出入,方便以后人员维护建议使用

title

JSON Schema文件的标题,非必填

description

JSON Schema文件的描述信息,非必填

type

待校验元素的类型(例如,最外层的type表示待校验的是一个JSON对象,内层type分别表示待校验的元素类型为,可以是object、array、null、number,string,array,object)

properties

JSON对象中,各个key-value对中value的限制条件

required

校验的JSON对象中,必须存在的key,不存在则校验失败

:type可以使用数组表示,表示多种类型。例如:

{ "type": "number" }
42 //√
42.0 //√
"42" //×

{ "type": ["number", "string"] }
42 //√
42.0 //√
"42" //√

接下里来,具体看下每种类型的具体使用。

3、JSON Schema 语法:

3.1)string类型:

用来约束json数据中value的类型,此外还可以通过一些属性来具体约束value的长度、正则...

1)minLength、maxLength:

{
"type": "string",
"minLength": 2,
"maxLength": 3
}

"A" //×
"ABCD" //×
"ABC" //√

2)正则表达式:

正则表达式语法是JavaScript(特别是​​ECMA 262​​​)中定义的语法。具体可以查看:​​http://json-schema.org/understanding-json-schema/reference/regular_expressions.html#regular-expressions​​

{
"type": "string",
"pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
}

"555-1212" //√
"(888)555-1212 ext. 532" //×

3)Format:

不常用,值只能是以下的取值date-time(时间格式)、email(邮件格式)、hostname(网站地址格式)、ipv4、ipv6、uri、uri-reference、uri-template、json-pointer。假如要校验的字符串是邮箱格式的可以使用"forma":"email",而不用pattern自己去指定正则表达式。

3.2)integer、number类型:

integer表示整型,number表示浮点型数据。

:对“整数”类型的精确处理可能取决于JSON Schema验证程序的实现,JavaScript(以及JSON)没有整数和浮点值的不同类型。因此,JSON Schema不能单独使用类型来区分整数和非整数。JSON Schema规范建议(但不要求)验证者使用数学值确定数字是否为整数,而不是单独的类型。因此,在这一点上,验证者之间存在一些分歧。例如,基于JavaScript的验证器可以接受1.0作为整数,而基于Python的jsonschema不接受。

1)multipleOf:

可以使用关键字multipleOf将数字限制为给定数字的倍数。

{
"type" : "number",
"multipleOf" : 10
}
20 //√
23 //×

2)range:

  • x ≥ minimum
  • x > exclusiveMinimum
  • x ≤ maximum
  • x < exclusiveMaximum
{
"type": "number",
"minimum": 0,
"exclusiveMaximum": 100
}

-1 //×
100 //×
99 //√

3.3)boolean:

{ "type": "boolean" }
true //√
false //√
0 //×
"true" //×

3.4)null:

{ "type": "null" }
null //√
false //×
0 //×
"" //×

3.5)object:

1)properties:

使用properties关键字定义对象上的属性(键值对)。属性的值是一个对象,其中每个键是json数据中的属性名称,每个值是用于验证该属性的JSON Schema。

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string"
}
}
}

{} //√
{"id":1} //√
{"name":"test"} //√
{"id":1,"name":"test"} //√
{"id":1,"name":"test","other":1} //√

可以使用enum指定某个字段的值。例如:

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string",
"enum": ["a", "b"]
}
}
}
{} //√
{"name":"a"} //√
{"name":""} //×
{"name":"c"} //×

2)additionalProperties :

additionalProperties关键字用于控制json数据中的字段是否允许超过JSON Schema中定义的字段。默认情况下允许,additionalProperties值可以是布尔型,也可以是对象(用来指定允许哪些类型)

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
}

{} //√
{"id":1} //√
{"name":"test"} //√
{"id":1,"name":"test"} //√
{"id":1,"name":"test","other":1} //×

也可以通过additionalProperties控制允许哪些类型的字段,例如:

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
}

{} //√
{"id":1} //√
{"name":"test"} //√
{"id":1,"name":"test"} //√
{"id":1,"name":"test","other":"1"} //√
{"id":1,"name":"test","other":1} //×

3)required

默认,json数据中的字段可以比JSON Schema中定义的字段多或者少。可以使用additionalProperties 来控制json数据中的字段不能多于JSON Schema中定义的字段;同样,可以使用required控制某些JSON Schema中的字段,必须要在json数据中出现。

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string"
}
},
"required": [
"name"
]
}

{} //×
{"id":1} //×
{"name":"test"} //√
{"id":1,"name":"test"} //√
{"id":1,"name":"test","other":1} //√

 4)Pattern Properties:

additionalProperties 和required可以限制json中的字段是否符合JSON Schema中的定义。可以进一步通过pattern来限制那些符合某些正则的字段。

{
"type": "object",
"patternProperties": {
"^S_": { "type": "string" },
"^I_": { "type": "integer" }
},
"additionalProperties": false
}

{} //√
{ "S_25": "This is a string" } //√
{ "I_0": 42 } //√
{"a":1} //×
{"b":"b"} //×

5)Property names:

draft6新特性,Property names可以根据schema验证属性的名称,而不管其值、类型如何。如果您不想强制使用特定的属性,但是要确保这些属性的名称遵循特定的约定,这将很有用。

{
"type": "object",
"propertyNames": {
"pattern": "^a"
}
}

{} //√
{"a":1} //√
{"a":"1"} //√
{"a":{}} //√
{"a":[]} //√
{"b":1} //×

6)Property dependencies:

我们使用dependencies关键字表示一个属性对另一个属性的依赖。 dependency关键字的值是一个对象。对象中的每个条目都从属性名p映射到列出存在p时所需的属性的字符串数组。

{
"type": "object",

"properties": {
"name": { "type": "string" },
"credit_card": { "type": "number" },
"billing_address": { "type": "string" }
},
"dependencies": {
"credit_card": ["billing_address"]
}
}

{"name":"John Doe","credit_card":555,"billing_address":"555 Debtor's Lane"}//√
{"billing_address":"555 Debtor's Lane"}//√
{"credit_card":555} //×

7)Schema dependencies:

Schema dependencies的工作方式类似于Property dependencies,但是它们不仅可以指定其他必需的属性,还可以扩展模式使其具有其他约束。

8)size:

{
"type": "object",
"minProperties": 2,
"maxProperties": 3
}

{ "a": 0, "b": 1 } //√
{ "a": 0, "b": 1, "c": 2 } //√
{ "a": 0 }//×
{} //×

3.6)array:

{ "type": "array" }

[1, 2, 3, 4, 5] //√
[3, "different", { "types" : "of values" }] //√

1)items:

可以使用items限制数组中元素的类型。

{
"type": "array",
"items": {
"type": "number"
}
}
[] //√
[1, 2, 3, 4, 5] //√
[1, 2, "3", 4, 5] //×

此外,可以通过items来指定数组中每个元素的类型。(有顺序要求的)

{
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "string"
}
]
}
[1] //√
[1,"Pennsylvania"] //√
[1, "Pennsylvania",1] //√
["Pennsylvania"] //×
["Pennsylvania",1] //×

同时,也可以使用additionalItems来限制是否允许其他类型存在。

{
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "string"
}
],
"additionalItems": false
}
[1] //√
[1,"Pennsylvania"] //√
["Pennsylvania"] //×
["Pennsylvania",1] //×
[1, "Pennsylvania",1] //×

2)contains:

draft6新增特性。items是校验数组中每个元素类型,contains用来校验一个或多个元素。

{
"type": "array",
"contains": {
"type": "number"
}
}
["life", "universe", "everything", 42] //√
["life", "universe", "everything"] //×

3)Tuple validation:

可以使用enum,对数组中每个元素的取值进行校验。例如:

{
"type": "array",
"items": [
{
"type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
},
{
"type": "string",
"enum": ["NW", "NE", "SW", "SE"]
}
]
}
["Avenue", "NW"] //√
["Avenue", "2NW"] //×

4)length:

{
"type": "array",
"minItems": 2,
"maxItems": 3
}
[] //√
[1,2,] //√
[1,2,3] //√
[1,2,3,4] //×

5)uniqueness:

{
"type": "array",
"uniqueItems": true
}
[] //√
[1, 2, 3, 4, 5] //√
[1, 2, 3, 4, 5, 5] //×

4、高级篇:

4.1)combining schemas:

可以使用allOf、anyOf、oneOf、not 将多个JSON Schema组合起来使用,形成具有一定逻辑关系的schema。

{
"oneOf": [
{ "type": "number", "multipleOf": 5 },
{ "type": "number", "multipleOf": 3 }
]
}

4.2)reuse:

重用是编程中最核心的思想之一。JSON Schema也可以重用。

1)definitions、$ref:

我们可以将一个JSON Schema放到definitions中,供其他地方重用。可以通过$ref来引用definitions中的schema。(通过​​JSON Pointer​​)

2)看一个例子:

{
"$schema": "http://json-schema.org/draft-06/schema#",

"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
},

"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/address" },
"shipping_address": { "$ref": "#/definitions/address" }
},
"required": ["shipping_address", "billing_address"]
}

//json
{
"shipping_address": {
"street_address": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC"
},
"billing_address": {
"street_address": "1st Street SE",
"city": "Washington",
"state": "DC"
}
}

4.3)Recursion(递归):

$ ref元素可用于创建引用自己的递归模式。例如,您可能具有一个包含多个子级的人员模式,每个子级也是人员实例。

{
"$schema": "http://json-schema.org/draft-07/schema#",

"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string" },
"children": {
"type": "array",
"items": { "$ref": "#/definitions/person" },
"default": []
}
}
}
},

"type": "object",

"properties": {
"person": { "$ref": "#/definitions/person" }
}
}

//json
{
"person": {
"name": "Elizabeth",
"children": [
{
"name": "Charles",
"children": [
{
"name": "William",
"children": [
{ "name": "George" },
{ "name": "Charlotte" }
]
},
{
"name": "Harry"
}
]
}
]
}
}

4.4)$id:

可以使用$id属性指向一个有效的URL。

{ "$id": "http://foo.bar/schemas/address.json" }

 


举报

相关推荐

0 条评论