“Understanding JSON Schema”官方文檔翻譯和解讀

“Understanding JSON Schema”官方文檔翻譯和解讀
---Release 7.0

一. 基礎(chǔ)

{ }
接受任何有效的JSON

true
接受任何有效的JSON,等同于{ }

false
不匹配任何的JSON

type
關(guān)鍵字的基本類型
type的值可以是單個(gè),也可以是一個(gè)list

$schema
聲明這是一個(gè)schema, 還可以聲明它針對(duì)的是哪個(gè)特定的版本
例如:
"$schema": "http://json-schema.org/schema#"

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

$id
聲明整個(gè)架構(gòu)的唯一標(biāo)識(shí)符
聲明一個(gè)用于$ref解析URI的基URI
例如:
聲明頂級(jí)架構(gòu)的$id
{ "$id": "http://foo.bar/schemas/address.json" }
當(dāng)引用{ "$ref": "person.json" }時(shí)
將試圖從http://foo.bar/schemas/person.json這個(gè)地址來(lái)獲取person.json
即使address.json是從其他地方加載的...

$id還提供了一種在不使用JSON指針的情況下引用子模式的方法.這表示可以通過(guò)唯一的名稱來(lái)引用它們,而不是它們?cè)贘SON數(shù)中的位置.
例如:
address對(duì)象的"$id": "#address"
則當(dāng)引用時(shí),可直接使用{ "$ref": "#address" }

注意:python的jsonschema庫(kù)暫時(shí)不支持此功能.

二. 特定類型關(guān)鍵字

type的取值:
string, integer, number, object, array, boolean, null

2.1 string

{ "type": "string" }

minLengthmaxLength
約束字符串長(zhǎng)度
例如:

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

pattern
將字符串限制為特定的正則表達(dá)式

format
對(duì)常用的某些字符串進(jìn)行基本語(yǔ)義驗(yàn)證.允許將值限制為超出JSON Schema中的其他工具.

日期和時(shí)間
"date-time": Date and time together, for example, 2018-11-13T20:20:39+00:00.
"time": New in draft 7 Time, for example, 20:20:39+00:00
"date": New in draft 7 Date, for example, 2018-11-13.

Email地址
"email": Internet email address, see RFC 5322, section 3.4.1.
"idn-email": New in draft 7 The internationalized form of an Internet email address, see RFC 6531.

Hostnames
"hostname": Internet host name, see RFC 1034, section 3.1.
"idn-hostname": New in draft 7 An internationalized Internet host name, see RFC5890, section 2.3.2.3.

IP地址
"ipv4": IPv4 address, according to dotted-quad ABNF syntax as defined in RFC 2673, section 3.2.
"ipv6": IPv6 address, as defined in RFC 2373, section 2.2.

資源標(biāo)識(shí)符
"uri": A universal resource identifier (URI), according to RFC3986.
"uri-reference": New in draft 6 A URI Reference (either a URI or a relative-reference), according to RFC3986, section 4.1.
"iri": New in draft 7 The internationalized equivalent of a “uri”, according to RFC3987.
"iri-reference": New in draft 7 The internationalized equivalent of a “uri-reference”, according to RFC3987
如果模式中的值能夠相對(duì)于特定源路徑(例如來(lái)自網(wǎng)頁(yè)的鏈接),則通常更好的做法是使用 "uri-reference"(或"iri-reference")而不是"uri"(或 "iri")。"uri"只應(yīng)在路徑必須是絕對(duì)路徑時(shí)使用。

URI模板
"uri-template":草案6中的新內(nèi)容根據(jù)RFC6570的 URI模板(任何級(jí)別) 。如果您還不知道URI模板是什么,則可能不需要此值。

JSON指針
"json-pointer":根據(jù)RFC6901 ,草案6中的新功能 JSON指針。在結(jié)構(gòu)化復(fù)雜模式中,有更多關(guān)于JSON指針在JSON模式中的使用的討論。請(qǐng)注意,僅當(dāng)整個(gè)字符串僅包含JSON指針內(nèi)容時(shí)才應(yīng)使用此選項(xiàng).
例如 /foo/bar
而 #/foo/bar/ 應(yīng)該使用 "uri-reference"
"relative-json-pointer":草案7中的新內(nèi)容相對(duì)JSON指針。

正則表達(dá)式
"regex":草案7中的新內(nèi)容正則表達(dá)式,根據(jù)ECMA 262 方言應(yīng)該有效

2.2 integer

{"type": "integer"}
代表整數(shù)

警告:
“整數(shù)”類型的精確處理可能取決于JSON模式驗(yàn)證器的實(shí)現(xiàn)。JavaScript(以及JSON)沒(méi)有針對(duì)整數(shù)和浮點(diǎn)值的不同類型。因此,JSON Schema不能單獨(dú)使用類型來(lái)區(qū)分整數(shù)和非整數(shù)。JSON Schema規(guī)范建議但不要求驗(yàn)證器使用數(shù)學(xué)值來(lái)確定數(shù)字是否為整數(shù),而不是單獨(dú)的類型。因此,在這一點(diǎn)上驗(yàn)證者之間存在一些分歧。例如,基于JavaScript的驗(yàn)證器可以接受1.0為整數(shù),而基于Python的jsonschema則不接受。

所以可以使用multipleOf關(guān)鍵字來(lái)解決這種差異
例如:
{ "type": "number", "multipleOf": 1.0 }
可以匹配42,也可以匹配42.0
但不能匹配3.1415926

2.3 number

{"type": "number"}
匹配任何數(shù)字類型,包括整數(shù),浮點(diǎn)數(shù)甚至指數(shù)表示法.

multipleOf
可匹配給定數(shù)字的倍數(shù),它的取值可以使任何正數(shù).
例如:

{
  "type"       : "number",
  "multipleOf" : 10
}

則代表匹配10的倍數(shù).
0,10,20等等都是正向用例.

minimummaximum

minimum <= X <= maximum

exclusiveMinimumexclusiveMaximum

exclusiveMinimum < X < exclusiveMaximum

注意,在草案4中,exclusiveMinimum和 exclusiveMaximum的取值是 true 或 false.

2.4 object

{ "type": "object" }

properties
定義對(duì)象上的屬性(鍵值對(duì))

required
必須出現(xiàn)的字段

additionalProperties
控制額外內(nèi)容的處理,即名稱未在properties中列出的屬性.默認(rèn)允許任何其他屬性.
該關(guān)鍵字可以是一個(gè)布爾值或?qū)ο?
如果是布爾值并設(shè)置為false,則不允許其他屬性出現(xiàn).
如果是對(duì)象,則該對(duì)象是將用于驗(yàn)證未列出的任何其他屬性的模式
例如:
允許其他屬性出現(xiàn),但前提是他們的值都是字符串:
"additionalProperties": { "type": "string" }
因此當(dāng)某一個(gè)不存在的properties的值不是字符串類型時(shí),將報(bào)錯(cuò).

propertyNames
只驗(yàn)證屬性的名稱,而不校驗(yàn)它的值.
例如:

{
  "type": "object",
  "propertyNames": {
    "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
  }
}

只有匹配該正則的屬性名稱才被認(rèn)為有效.并且一定是字符串.(因?yàn)閷?duì)象鍵無(wú)論如何必須始終是字符串)

patternProperties
驗(yàn)證屬性的名稱符合正則并且指定它的屬性
例如:

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

以上架構(gòu)驗(yàn)證了以前綴S_開(kāi)頭的任何其他屬性必須是字符串,以前綴為I_開(kāi)頭的任何其他屬性必須是整數(shù).

patternPropertiesadditionalProperties可以結(jié)合使用.
例如:

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

以上表示當(dāng)屬性既不是內(nèi)置的,也不匹配patternProperties時(shí), 它的值必須是string.

minPropertiesmaxProperties
限制對(duì)象上的屬性數(shù)量.必須是非負(fù)整數(shù).
例如:

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

該schema匹配只有兩個(gè)或三個(gè)屬性名稱的對(duì)象.

dependencies

屬性依賴
dependencies關(guān)鍵字表示一個(gè)屬性,對(duì)另一個(gè)屬性的依賴關(guān)系.
它的值是一個(gè)對(duì)象,對(duì)象中的每個(gè)條目都從屬性名稱銀蛇到一個(gè)字符串?dāng)?shù)組,列出了該屬性名稱存在時(shí)所需的屬性.
例如:

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

該schema描述了,每當(dāng)存在credit_card時(shí),還必須存在billing_address
但這個(gè)依賴不是雙向的. 當(dāng)存在billing_address時(shí),沒(méi)有credit_card也是可以的.
當(dāng)我們需要定義一個(gè)雙向的依賴關(guān)系時(shí),可以這樣處理:

{
  "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"]
  }
}

模式依賴
作用類似于屬性依賴項(xiàng),但他們不是僅指定其他必須屬性,而是可以擴(kuò)展模式以具有其他約束.
例如:

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

2.5 array

{ "type": "array" }

列表驗(yàn)證
items
任意長(zhǎng)度的序列,其中每個(gè)項(xiàng)目匹配相同的模式。
對(duì)于這種數(shù)組,items就是單個(gè)的schema,這個(gè)schema用于驗(yàn)證數(shù)組中的所有項(xiàng).
當(dāng)items是單個(gè)schema時(shí), additionalItems這個(gè)關(guān)鍵字沒(méi)有意義.
items的值是一個(gè)對(duì)象{ }

contains
雖然items必須對(duì)數(shù)組中的每個(gè)項(xiàng)有效, 但是contains只需要針對(duì)數(shù)組中的一個(gè)或多個(gè)項(xiàng)進(jìn)行驗(yàn)證
例如:

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

只要被驗(yàn)證項(xiàng)中存在一個(gè)number,該項(xiàng)就被驗(yàn)證成功了.

元組驗(yàn)證
items
每個(gè)字段都有不同的架構(gòu).此時(shí)items的值是一個(gè)list[ ]
此時(shí)按索引序號(hào)進(jìn)行驗(yàn)證.

additionalItems
當(dāng)該關(guān)鍵字的值為布爾值時(shí),
該關(guān)鍵字控制當(dāng)超出所定義的數(shù)組中的其他項(xiàng)時(shí),是否有效.
默認(rèn)情況下如果沒(méi)有這個(gè)字段或值為true,是允許其他額外項(xiàng)的.
當(dāng)該關(guān)鍵字的值是一個(gè)對(duì)象時(shí)
該關(guān)鍵字將對(duì)額外項(xiàng)進(jìn)行描述
例如:

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

這個(gè)列表中的額外項(xiàng)必須是string類型.

minItemsmaxItems
指定數(shù)組的長(zhǎng)度

uniqueItems
確保數(shù)組中的每個(gè)項(xiàng)都是唯一的.

2.6 boolean

{ "type": "boolean" }
該字段只接收布爾值

2.7 null

{ "type": "null" }
該字段只能必須是null
false, 0, "" 都不能通過(guò)校驗(yàn)

三. 通用關(guān)鍵字

3.1 注釋類

title
description
default
examples
這四個(gè)關(guān)鍵字都不用于驗(yàn)證,只用來(lái)描述.并且也不是必須的.

3.2 評(píng)論

$comment
草案7新增關(guān)鍵字.用于向jsonschema添加注釋.它的值必須始終是一個(gè)字符串.

3.3 枚舉

enum
該關(guān)鍵字用于限制值,它必須是一個(gè)至少包含一個(gè)元素的數(shù)組,并且其中每一個(gè)元素都是唯一的.
enum即便沒(méi)有被標(biāo)明類型,也仍然可以接受不同類型的值.
但是如果type被定義,即便該值在enum中,也必須遵循type原則.

3.4 常數(shù)

const
該字段用于將值限值為單個(gè)值.

四. 媒體:字符串編碼,非JSON數(shù)據(jù)

contentMediaType
該關(guān)鍵字指定媒體類型
支持的類型參見(jiàn):
http://www.iana.org/assignments/media-types/media-types.xhtml
但具體仍然要取決于應(yīng)用程序和操作系統(tǒng).
對(duì)web很重要的MIME類型參見(jiàn):
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
例如:

{
  "type": "string",
  "contentMediaType": "text/html"
}

該模式指定了一個(gè)包含HTML文檔的字符串
正確的匹配示例:

"<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head></html>"

contentEncoding
該關(guān)鍵字用于指定存儲(chǔ)內(nèi)容
可接受的值為7bit,8bit,binary,quoted-printable 和base64。
如果內(nèi)容是二進(jìn)制的數(shù)據(jù),可設(shè)置為base64,這將包括許多圖像類型,例如 image/png 或音頻類型,例如 audio/mpeg
例如:

{
  "type": "string",
  "contentEncoding": "base64",
  "contentMediaType": "image/png"
}

該模式表示字符串包含使用base64編碼的PNG圖像
正確的匹配示例:

"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAA..."

五. 組合模式

  • allOf:必須對(duì)所有子模式有效
  • anyOf:必須對(duì)任何子模式有效
  • oneOf:必須對(duì)其中一個(gè)子模式有效

allOf
給定值必須對(duì)所有給定的子schema有效
例如:

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

則:
"short"為正確匹配
"too long"為錯(cuò)誤匹配

邏輯上不可能成立的schema:

{
   "allOf": [
     { "type": "string" },
     { "type": "number" }
   ]
}

anyOf
給定值必須對(duì)任何一個(gè)或多個(gè)給定的子schema有效.
只要一個(gè)值對(duì)這些schema中的任何一個(gè)進(jìn)行驗(yàn)證成功,則認(rèn)為它對(duì)整個(gè)組合schema有效
例如:

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

則:
"short"為正確匹配
"too long" 為錯(cuò)誤匹配
12 為正確匹配
-5 為錯(cuò)誤匹配

oneOf
給定值必須僅對(duì)其中一個(gè)給定子schema有效
例如:

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

則:
10為正確匹配
9 為正確匹配
2 為錯(cuò)誤匹配,因?yàn)樗皇?或3的倍數(shù)。
15 為錯(cuò)誤匹配,因?yàn)樗ヅ涠鄠€(gè)

可以分解子schema的公共部分
例如:以下schema等同于上述schema

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

not
例如:
{ "not": { "type": "string" } }
則:
42 為正確匹配
{ "key": "value" } 為正確匹配,因?yàn)樗且粋€(gè)對(duì)象
"I am a string" 為錯(cuò)誤匹配

六. 有條件地應(yīng)用子模式

if, thenelse 關(guān)鍵字
如果if生效,則then必須生效,然后else會(huì)被忽略
如果if無(wú)效,則else必須生效,then會(huì)被忽略.
例如:
假設(shè)您想編寫一個(gè)模式來(lái)處理美國(guó)和加拿大的地址。這些國(guó)家/地區(qū)有不同的郵政編碼格式,我們希望根據(jù)國(guó)家/地區(qū)選擇要驗(yàn)證的格式。如果地址在美國(guó),則該postal_code字段為“zipcode”:五個(gè)數(shù)字后跟可選的四位數(shù)后綴。如果地址位于加拿大,則該postal_code字段是六位數(shù)的字母數(shù)字字符串,其中字母和數(shù)字交替顯示。

{
   "type": "object",
   "properties": {
     "street_address": {
       "type": "string"
     },
     "country": {
       "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]" } }
   }
}

則:

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

為正確校驗(yàn)

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

為正確校驗(yàn)

{
  "street_address": "24 Sussex Drive",
  "country": "Canada",
  "postal_code": "10000"
}

為錯(cuò)誤校驗(yàn)

當(dāng)需要處理兩個(gè)以上的內(nèi)容時(shí), 可以用if和then ,然后用allOf關(guān)鍵字把它們包裹起來(lái).

例如:

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

則:

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

為正確校驗(yàn)

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

為正確校驗(yàn)

{
  "street_address": "Adriaan Goekooplaan",
  "country": "Netherlands",
  "postal_code": "2517 JX"
}

為正確校驗(yàn)

{
  "street_address": "24 Sussex Drive",
  "country": "Canada",
  "postal_code": "10000"
}

為錯(cuò)誤校驗(yàn)

十. 構(gòu)建jsonschema的復(fù)雜模式

10.1 重用

我們可以使用$ref關(guān)鍵字從其他地方引用此架構(gòu)片段 。

{ "$ref": "#/definitions/address" }

完整舉例:

{
   "$schema": "http://json-schema.org/draft-07/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" }
   }
}

$ref也可以是相對(duì)或絕對(duì)URI,因此如果您希望將定義包含在單獨(dú)的文件中,也可以這樣做。
例如:

{ "$ref": "definitions.json#/address" }

將從另一個(gè)文件中加載地址模式。

10.2 遞歸

$ref元素可用于創(chuàng)建引用自身的遞歸模式。例如,您可能擁有一個(gè)person包含數(shù)組的模式children,每個(gè)模式也是person實(shí)例。
例如:

{
   "$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" }
   }
}

則:
英國(guó)王室樹(shù)的片段:

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

可通過(guò)校驗(yàn)

上面,我們創(chuàng)建了一個(gè)引用自身另一部分的模式,有效地在驗(yàn)證器中創(chuàng)建了一個(gè)“循環(huán)”,這既是允許的又是有用的。但請(qǐng)注意,相互$ref引用的模式循環(huán)可能會(huì)導(dǎo)致解析器中的無(wú)限循環(huán),并且明確禁止。
例如:

{
   "definitions": {
     "alice": {
       "anyOf": [
         { "$ref": "#/definitions/bob" }
       ]
     },
     "bob": {
       "anyOf": [
         { "$ref": "#/definitions/alice" }
       ]
     }
   }
}

10.3 擴(kuò)展

當(dāng)$ref與組合關(guān)鍵字allOf, anyOf, oneOf 一起使用
舉例:

{
   "$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": {
       "allOf": [
         { "$ref": "#/definitions/address" },
         { "properties":
           { "type": { "enum": [ "residential", "business" ] } },
           "required": ["type"]
         }
       ]
     }
   }
}

以上模式首先定義了一個(gè)address的模式. 下方具體字段有賬單地址, 他的模式與address相同. 有送貨地址, 該地址除了與address模式要相同以外,還必須額外存在一個(gè)type字段.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容