当前位置 : 首页 » 文章分类 :  开发  »  JsonSchema

JsonSchema

Json Schema

JSON Schema 规范(中文版)
https://json-schema.apifox.cn/

在线 Json Schema 校验
https://www.lddgo.net/string/json-schema


数据类型

https://json-schema.org/understanding-json-schema/reference/type

JSON Schema 据类型:

string
number
integer
object
array
boolean
null

array 数组

minItems 和 maxItems 数组长度

可以使用 minItems 和 maxItems 关键字指定数组的长度。每个关键字的值必须是非负数:

{
  "type": "array",
  "minItems": 2,
  "maxItems": 3
}

[]  // not OK,
[1]  // not OK,
[1, 2] // OK
[1, 2, 3] // OK
[1, 2, 3, 4]  // not OK

通用关键字

$schema 版本/方言(Dialect)

JSON Schema 的一个版本称为方言。每个 JSON Schema 版本都是 JSON Schema 的新方言。
该 $schema 关键字用于声明模式是针对哪种 JSON 方言编写的。$schema 关键字的值也是模式的标识符,可用于根据方言 $schema 标识验证模式是否有效。
建议所有 JSON 模式都有一个 $schema 关键字来与读者和工具进行交流,以了解预期的规范版本。

type 数据类型

type关键字可以是一个字符串或数组:

  • 如果是字符串,则是上述基本类型之一的名称。
  • 如果是数组,则必须是字符串数组,其中每个字符串是其中一种基本类型的名称,每个元素都是唯一的。在这种情况下,如果 JSON 片段与_任何_给定类型匹配,则它是有效的。
{ "type": "number" }

42 // OK
42.0 // OK
"42" //not ok。这不是一个数字,它是一个包含数字的字符串。
{ "type": ["number", "string"] }

42 // OK
"Life, the universe, and everything" // OK

["Life", "the universe", "and everything"] // not OK

对于这些类型中的每一种,都有仅适用于这些类型的关键字。例如,数字类型有一种指定数字范围的方法,这不适用于其他类型。


properties 对象属性

对象的属性(键值对)是使用 properties 关键字定义的 。properties 的值是一个对象,其中每个键是属性的名称,每个值是用于验证该属性的模式。
例如,我们要为由数字、街道名称和街道类型组成的地址定义一个简单的模式:

{
  "type": "object",
  "properties": {
    "number": { "type": "number" },
    "street_name": { "type": "string" },
    "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
  }
}

// OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }

// not OK,提供的号码类型错误,则无效
{ "number": "1600", "street_name": "Pennsylvania", "street_type": "Avenue" }

// OK,默认情况下,省略属性是有效的。请参阅必需属性。
{ "number": 1600, "street_name": "Pennsylvania" }

// OK,通过扩展,即使是空对象也是有效的
{ }

// OK,默认情况下,提供附加属性是有效的:
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" }

additionalProperties 额外属性

additionalProperties 额外属性用于控制不在 properties 或 patternProperties 中出现的属性。
默认情况下,允许任何其他属性
将 additionalProperties 设置为 false 意味着不允许其他属性。

例1,不允许额外属性

{
  "type": "object",
  "properties": {
    "number": { "type": "number" },
    "street_name": { "type": "string" },
    "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
  },
  "additionalProperties": false
}

// OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }

 // not OK,额外属性“direction”使对象无效
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" }

例2,允许额外属性,但要满足模式,必须是字符串:

{
  "type": "object",
  "properties": {
    "number": { "type": "number" },
    "street_name": { "type": "string" },
    "street_type": { "enum": ["Street", "Avenue", "Boulevard"] }
  },
  "additionalProperties": { "type": "string" }
}

// OK
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue" }

// OK,这是有效的,因为附加属性的值是一个字符串
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "direction": "NW" }

 // not OK,这是无效的,因为附加属性的值不是字符串:
{ "number": 1600, "street_name": "Pennsylvania", "street_type": "Avenue", "office_number": 201 }

例3,properties, patternProperties, additionalProperties 组合使用

{
  "type": "object",
  "properties": {
    "builtin": { "type": "number" }
  },
  "patternProperties": {
    "^S_": { "type": "string" },
    "^I_": { "type": "integer" }
  },
  "additionalProperties": { "type": "string" }
}

// OK
{ "builtin": 42 }

// OK,这是一个不匹配任何正则表达式的键:
{ "keyword": "value" }

 // not OK,额外属性必须是一个字符串:
{ "keyword": 42 }

// OK,I_int 满足 patternProperties,额外属性 keyword 是字符串
{ "I_int": 34, "keyword": "value" }

required 必须字段

required 指定必需属性列表,required 关键字采用零个或多个字符串的数组。这些字符串中的每一个都必须是唯一的。

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "email": { "type": "string" },
    "address": { "type": "string" },
    "telephone": { "type": "string" }
  },
  "required": ["name", "email"]
}

// OK
{
  "name": "William Shakespeare",
  "email": "bill@stratford-upon-avon.co.uk"
}

// OK,提供额外的属性是可以的,即使是架构中没有定义的属性:
{
  "name": "William Shakespeare",
  "email": "bill@stratford-upon-avon.co.uk",
  "address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
  "authorship": "in question"
}

 // not OK,缺少必需的“email”属性会使 JSON 文档无效
{
  "name": "William Shakespeare",
  "address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
}

 // not OK,在 JSON 中,具有值的属性null不等同于不存在的属性。这失败,因为null不是“字符串”类型,而是“空”类型
{
  "name": "William Shakespeare",
  "address": "Henley Street, Stratford-upon-Avon, Warwickshire, England",
  "email": null
}

items 列表验证

单个 items 验证数组中所有元素

如果数组中每个项目都匹配相同的模式,可以将 items 关键字设置为单个模式,用于验证数组中所有元素。
当 items 是单模式时,additionalItems 关键字没有意义,不应使用。

定义数组中的每一项都是一个数字:

{
  "type": "array",
  "items": {
    "type": "number"
  }
}

[1, 2, 3, 4, 5] // OK
[1, 2, "3", 4, 5]  // not OK,单个“非数字”会导致整个数组无效
[] // OK,空数组始终有效

数组 items 指定数组中每个数据项的验证模式

如果数组中的元素是不同的模式,可以使用数组类型的 items 给每个数组项定义验证模式,每个 item 对应数组中一个元素项的验证模式,items 中的第一个元素验证数组中的第一个数据项,以此类推。

如下,items 定义了数组中第一个元素是数字,第二个元素是字符串,第三个元素的取值必须符合固定enum枚举,第四个元素取值也必须符合固定枚举。

{
  "type": "array",
  "items": [
    { "type": "number" },
    { "type": "string" },
    { "enum": ["Street", "Avenue", "Boulevard"] },
    { "enum": ["NW", "NE", "SW", "SE"] }
  ]
}

[1600, "Pennsylvania", "Avenue", "NW"] // OK
[24, "Sussex", "Drive"]  // not OK,“Drive”不是可接受的街道类型之一
["Palais de l'Élysée"]  // not OK,此地址缺少街道号码
[10, "Downing", "Street"] // OK,可以不提供所有项目
[1600, "Pennsylvania", "Avenue", "NW", "Washington"] // OK,默认情况下可以在尾部添加其他项目

enum 枚举值

enum 关键字用于将值限制为一组固定的值。它必须是一个包含至少一个元素的数组,其中每个元素都是唯一的。

{
  "enum": ["red", "amber", "green"]
}

"red" // OK
"blue"  // not OK

const 常数

Draft 6 中的新内容 const关键字被用于限制值为一个常量值。

{
  "properties": {
    "country": {
      "const": "United States of America"
    }
  }
}

{ "country": "United States of America" } // OK
{ "country": "Canada" }  // not OK

title 和 description

JSON Schema 包含一些关键字,它们并不严格用于验证,而是用于描述模式的一部分。这些“注释”关键字都不是必需的,但鼓励使用为了良好实践,并且可以使您的模式“自我记录”。
title 和 description 关键字必须是字符串。title 最好是简短的,而 description 提供模式描述的数据因此会有更长的说明。

default 默认值

default 关键字指定一个默认值。该值不用于在验证过程中填充缺失值。文档生成器或表单生成器等非验证工具可能会使用此值提示用户如何使用该值。但是,default 通常用于表示如果缺少某个值,则该值在语义上与该值与默认值一起存在时的语义相同。default 的值应该根据它所在的模式进行验证,但这不是必需的。


模式组合

allOf 必须满足所有子模式

要验证allOf,给定的数据必须针对给定的所有子模式有效。

{
  "allOf": [
    { "type": "string" },
    { "maxLength": 5 }
  ]
}

"short" // OK
"too long"  // not OK

anyOf 满足一个或多个子模式

要验证anyOf,数据必须满足任意一个或多个给定子模式。

{
  "anyOf": [
    { "type": "string", "maxLength": 5 },
    { "type": "number", "minimum": 0 }
  ]
}

"short" // OK
"too long"  // not OK
12 // OK
-5  // not OK

oneOf 满足且仅满足1个子模式

要验证oneOf,数据必须满足且只满足一个给定的子模式。

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

10 // OK
9 // OK

2  // not OK,不是 5 或 3 的倍数。
15  // not OK,同时符合两个子模式被拒绝。

not 不能满足子模式

{ "not": { "type": "string"} }

42 // OK
{ "key": "value" } // OK
"I am a string"  // not OK

if/then/else 条件语句

新的 Draft7 中 if,then 和 else 关键字允许基于另一种模式的结果来应用子模式,这很像传统编程语言中的 if/then/else 构造。
如果 if 有效,then 也必须有效(并忽略 else)。如果 if 无效,则 else 有效(并忽略 then)。

例,如果地址在美国,则该postal_code字段是“邮政编码”:五个数字后跟可选的四位后缀。如果地址在加拿大,则该postal_code字段是一个六位字母数字字符串,其中字母和数字交替出现

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "default": "United States of America",
      "enum": ["United States of America", "Canada"]
    }
  },
  "if": {
    "properties": { "country": { "const": "United States of America" } }
  },
  "then": {
    "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
  },
  "else": {
    "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
  }
}

// OK
{
  "street_address": "1600 Pennsylvania Avenue NW",
  "country": "United States of America",
  "postal_code": "20500"
}

// OK
{
  "street_address": "1600 Pennsylvania Avenue NW",
  "postal_code": "20500"
}

// OK
{
  "street_address": "24 Sussex Drive",
  "country": "Canada",
  "postal_code": "K1M 1M4"
}

 // not OK
{
  "street_address": "24 Sussex Drive",
  "country": "Canada",
  "postal_code": "10000"
}
// not OK
{
  "street_address": "1600 Pennsylvania Avenue NW",
  "postal_code": "K1M 1M4"
}

上一篇 MinIO

下一篇 Scrapy 爬虫

阅读
评论
3.1k
阅读预计14分钟
创建日期 2024-05-06
修改日期 2025-01-07
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论