在JSON中,对象是一种映射类型,它用来映射keys
和values
。在JSON
中,keys
必须是字符串。
// a schema
{ "type": "object" }
// success
{
"key": "value",
"another_key": "another_value"
}
// success
{
"Sun": 1.9891e30,
"Jupiter": 1.8986e27,
"Saturn": 5.6846e26,
"Neptune": 10.243e25,
"Uranus": 8.6810e25,
"Earth": 5.9736e24,
"Venus": 4.8685e24,
"Mars": 6.4185e23,
"Mercury": 3.3022e23,
"Moon": 7.349e22,
"Pluto": 1.25e22
}
// failure
"Not an object"
// failure
["An", "array", "not", "an", "object"]
使用properties
属性来定义对象上的属性。properties
的值是一个对象,它的每一个key
对应JSON
对象的每一个属性。
// a schema
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": {
"type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
}
}
// success
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }
// failure,number属性的值必须是数字
{ "number": "1600", "street_name": "Pennsylvania", "street_type": "Avenue" }
// success
{ "number": 1600, "street_name": "Pennsylvania" }
// success
{ }
// success
{
"number": 1600,
"street_name": "Pennsylvania",
"street_type": "Avenue",
"direction": "NW"
}
additionalProperties
关键字用于控制额外的属性,那些不在properties
里面的属性。
当然,默认是允许额外的属性。
additionalProperties
关键字的值为boolean或object,当additionalProperties
值设为boolean值且为false时,表示不允许任何额外的属性。
下面是一个additionalProperties
值为false的例子:
// a schema
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": {
"type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
},
"additionalProperties": false
}
// success
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }
// failure,多了direction属性
{
"number": 1600,
"street_name": "Pennsylvania",
"street_type": "Avenue",
"direction": "NW"
}
如果additionalProperties
值是一个对象,那么这个对象也是一个schema
,用来校验不在properties
列表中的属性。
// a schema
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": {
"type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
},
"additionalProperties": { "type": "string" }
}
// success
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }
// success
{
"number": 1600,
"street_name": "Pennsylvania",
"street_type": "Avenue",
"direction": "NW"
}
// failure,属性office_number值不是字符串类型
{
"number": 1600,
"street_name": "Pennsylvania",
"street_type": "Avenue",
"office_number": 210
}
默认情况下,properties
列表中的属性都不是必须的。当某些属性必须时,可以使用required
关键字。
required
值是一个长度大于1的数组,而且数组中的每个值都是唯一的。
// a schema
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "type": "string" },
"telephone": { "type": "string" }
},
"required": ["name", "email"]
}
// success
{
"name": "William Shakespeare",
"email": "bill@stratford-upon-avon.co.uk"
}
// success
{
"name": "William Shakespeare",
"email": "bill@stratford-upon-avon.co.uk",
"address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
"authorship": "in question"
}
// failure,缺少属性email
{
"name": "William Shakespeare",
"address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
}
可以使用minProperties
和maxProperties
关键字限制属性的个数。
// a schema
{
"type": "object",
"minProperties": 2,
"maxProperties": 3
}
// failure
{}
// failure
{ "a": 0 }
// success
{ "a": 0, "b": 1 }
// success
{ "a": 0, "b": 1, "c": 2 }
// failure
{ "a": 0, "b": 1, "c": 2, "d": 3 }
dependencies
允许schema根据某些特殊的属性存在而发生改变。
JSON Schema
中存在两种形式的依赖关系:
我们从简单的属性依赖关系开始。
例如,假设你有一个客户的schema,如果你有他们的信用卡号码,你也确保有他们的账单地址。
如果你没有他们的信用卡号码,你也不需要他们的账单地址。
我们使用dependencies
关键字来定义属性之间的依赖关系,dependencies
关键字的值是一个对象。
// a schema,其中如果存在credit_card属性,那么billing_address属性也必须存在
{
"type": "object",
"properties": {
"name": { "type": "string" },
"credit_card": { "type": "number" },
"billing_address": { "type": "string" }
},
"required": ["name"],
"dependencies": {
"credit_card": ["billing_address"]
}
}
// success
{
"name": "John Doe",
"credit_card": 5555555555555555,
"billing_address": "555 Debtor's Lane"
}
// failure
{
"name": "John Doe",
"credit_card": 5555555555555555
}
// success
{
"name": "John Doe"
}
// success,没有credit_card属性时,billing_address属性可以存在
{
"name": "John Doe",
"billing_address": "555 Debtor's Lane"
}
当然,如果想让credit_card
属性和billing_address
属性都存在时,可以定义相互依赖关系:
// a schema
{
"type": "object",
"properties": {
"name": { "type": "string" },
"credit_card": { "type": "number" },
"billing_address": { "type": "string" }
},
"required": ["name"],
"dependencies": {
"credit_card": ["billing_address"],
"billing_address": ["credit_card"]
}
}
// failure
{
"name": "John Doe",
"credit_card": 5555555555555555
}
// failure
{
"name": "John Doe",
"billing_address": "555 Debtor's Lane"
}
// success
{
"name": "John Doe",
"credit_card": 5555555555555555,
"billing_address": "555 Debtor's Lane"
}
Schema dependencies与Property dependencies相似,但它不是指定必须的属性,而是扩展让它拥有其他约束。
// a schema,当属性credit_card存在时,它需要额外定义属性billing_address
{
"type": "object",
"properties": {
"name": { "type": "string" },
"credit_card": { "type": "number" }
},
"required": ["name"],
"dependencies": {
"credit_card": {
"properties": {
"billing_address": { "type": "string" }
},
"required": ["billing_address"]
}
}
}
// success
{
"name": "John Doe",
"credit_card": 5555555555555555,
"billing_address": "555 Debtor's Lane"
}
// failure,失败,因为属性credit_card存在时,扩展了属性billing_address,而billing_address是必选属性
{
"name": "John Doe",
"credit_card": 5555555555555555
}
// success,默认情况下,没有additionalProperties关键字时,可随意添加额外的属性
{
"name": "John Doe",
"billing_address": "555 Debtor's Lane"
}
正如前面所描述的,additionalProperties
关键字可以限制对象,使它可以不显示的指定其他属性,也可以显示的指定属性的schema结构。
而这些,有时候还不够,你可能需要指定某些属性,属性名符合某种规则。而这时候就需要用到patternProperties
。
它从正则表达式映射过来,如果附加的属性符合给定的正则表达式,那么必须对该属性进行校验。
// a schema,以S_开头的属性必须时字符串类型,以I_开头的属性必须时整数类型
{
"type": "object",
"patternProperties": {
"^S_": { "type": "string" },
"^I_": { "type": "integer" }
},
"additionalProperties": false
}
// success
{ "S_25": "This is a string" }
// success
{ "I_0": 42 }
// faliure
{ "S_0": 42 }
// faliure
{ "I_42": "This is a string" }
// faliure,additionalProperties为false
{ "keyword": "value" }
patternProperties
可以和additionalProperties
结合使用。在这种情况下,
additionalProperties
将引用properties中未列出的任何属性,并且不匹配patternProperties
。
// a schema
{
"type": "object",
"properties": {
"builtin": { "type": "number" }
},
"patternProperties": {
"^S_": { "type": "string" },
"^I_": { "type": "integer" }
},
"additionalProperties": { "type": "string" }
}
// success
{ "builtin": 42 }
// success
{ "keyword": "value" }
// failure
{ "keyword": 42 }