参考

数组

数组用于有序元素。在 JSON 中,数组中的每个元素都可能是不同类型。

特定语言信息:
Python
Ruby
Objective-C
Swift

在 Python 中,"array" 等同于 listtuple 类型,具体取决于使用情况。但是,Python 标准库中的 json 模块始终使用 Python 列表来表示 JSON 数组。

模式
{ "type": "array" }
数据
[1, 2, 3, 4, 5]
符合模式
数据
[3, "different", { "types": "of values" }]
符合模式
数据
{"Not": "an array"}
不符合模式

JSON 中通常有两种使用数组的方式

  • 列表验证:任意长度的序列,其中每个项目都匹配相同的 模式.
  • 元组验证:固定长度的序列,其中每个项目可能具有不同的模式。在此用法中,每个项目的索引(或位置)对于解释值的方式具有重要意义。(此用法通常在某些编程语言中被赋予一个完全独立的类型,例如 Python 的 tuple)。

项目

列表验证对于任意长度的数组很有用,其中每个项目都匹配相同的模式。对于这种数组,设置 items 关键字 为单个模式,该模式将用于验证数组中的所有项目。

在以下示例中,我们定义数组中的每个项目都是一个数字

模式
{ "type": "array", "items": { "type": "number" }}
数据
[1, 2, 3, 4, 5]
符合模式

单个“非数字”会导致整个数组无效

数据
[1, 2, "3", 4, 5]
不符合模式

空数组始终有效

数据
[]
符合模式

元组验证

元组验证在数组是项目集合时很有用,其中每个项目都有不同的模式,并且每个项目的序数索引是有意义的。

例如,您可以将街道地址(例如 1600 Pennsylvania Avenue NW)表示为以下形式的 4 元组

数据
[number, street_name, street_type, direction]

[number, street_name, street_type, direction]

这些字段中的每一个都将具有不同的模式

  • number: 地址编号。必须是数字。
  • street_name: 街道名称。必须是字符串。
  • street_type: 街道类型。应为来自固定值集的字符串。
  • direction: 地址的城市象限。应为来自不同值集的字符串。

为此,我们使用 prefixItems 关键字。 prefixItems 是一个数组,其中每个项目都是与文档数组的每个索引相对应的模式。也就是说,一个数组,其中第一个元素验证输入数组的第一个元素,第二个元素验证输入数组的第二个元素,等等。

草案特定信息
在草案 4 - 2019-09 中,元组验证由 items 关键字的替代形式处理。当 items 是一个模式数组而不是单个模式时,它会像 prefixItems 的行为一样。

这是示例模式

模式
{ "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ]}
数据
[1600, "Pennsylvania", "Avenue", "NW"]
符合模式

"Drive" 不是可接受的街道类型之一

数据
[24, "Sussex", "Drive"]
不符合模式

此地址缺少街道号码

数据
["Palais de l'Élysée"]
不符合模式

可以不提供所有项目

数据
[10, "Downing", "Street"]
符合模式

并且,默认情况下,也可以在末尾添加其他项目

数据
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
符合模式

附加项目

关键字 items 可用于控制在元组中是否允许在 prefixItems 定义之外添加其他项目。关键字 items 的值是一个模式,所有额外的项目都必须通过该模式才能通过关键字验证。

草案 4 - 2019-09
在 2020-12 草案之前,您将使用关键字 additionalItems 来约束元组上的额外项目。它的工作原理与 items 相同,只是名称发生了改变。
草案 6 - 2019-09
在草案 6 - 2019-09 中,如果在同一模式中不存在“元组验证”关键字 items,则关键字 additionalItems 将被忽略。

这里,我们将重用上面的示例模式,但将 items 设置为 false,这将禁止元组中的额外项目。

模式
{ "type": "array", "prefixItems": [ { "type": "number" }, { "type": "string" }, { "enum": ["Street", "Avenue", "Boulevard"] }, { "enum": ["NW", "NE", "SW", "SE"] } ], "items": false}
数据
[1600, "Pennsylvania", "Avenue", "NW"]
符合模式

可以不提供所有项目

数据
[1600, "Pennsylvania", "Avenue"]
符合模式

但是,由于 itemsfalse,我们无法提供额外的项目

数据
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
不符合模式

您可以使用非布尔模式来约束额外项目可以具有的值,以表达更复杂的约束。在这种情况下,我们可以说额外项目是允许的,只要它们都是字符串。

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

额外的字符串项目是可以接受的...

数据
[1600, "Pennsylvania", "Avenue", "NW", "Washington"]
符合模式

... 但是其他任何内容都不可以

数据
[1600, "Pennsylvania", "Avenue", "NW", 20500]
不符合模式

未评估项目

2019-09 草案新增内容

在想要添加或禁止数组中的额外项目时,unevaluatedItems 关键字非常有用。

unevaluatedItems 应用于任何未被 itemsprefixItemscontains 关键字评估的值。正如 unevaluatedProperties 只影响对象中的 属性unevaluatedItems 只影响数组中的 项目

注意!“未评估”并不意味着“未被 itemsprefixItemscontains 评估”。“未评估”意味着“未成功评估”或“评估结果不为真”。

就像 items 一样,如果您将 unevaluatedItems 设置为 false,您可以禁止数组中出现额外的项目。

模式
{ "prefixItems": [ { "type": "string" }, { "type": "number" } ], "unevaluatedItems": false}

这里,所有值都被评估。模式通过验证。

数据
["foo", 42]
符合模式

但在这里,模式验证失败,因为 "unevaluatedItems": false 指定不应存在额外的值。

数据
["foo", 42, null]
不符合模式

请注意,items 不会“查看” 实例 中的 allOfanyOfoneOf,这些实例位于同一 子模式 中。因此,在这个下一个例子中,items 忽略 allOf,因此无法进行验证。

模式
{ "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], "items": { "const": 2 }}
数据
[true, "a", 2]
不符合模式

但是,如果你用 unevaluatedItems 替换 items,那么同一个数组就可以验证。

模式
{ "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], "unevaluatedItems": { "const": 2 }}
数据
[true, "a", 2]
符合模式

你也可以创建一个“半闭合”的模式:当你想保留前两个参数,但在某些情况下又需要添加更多参数时,这种模式非常有用。(在某些情况下,对两个参数是“闭合”的,但在你需要的时候,对更多参数是“开放”的。)

模式
{ "$id": "https://example.com/my-tuple", "type": "array", "prefixItems": [ { "type": "boolean" }, { "type": "string" } ],
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}

此处,模式被“封闭”到两个数组项。 之后,您可以使用 $ref 添加另一个项,如下所示

模式
{ "$id": "https://example.com/my-extended-tuple", "$ref": "https://example.com/my-tuple", "prefixItems": [ { "type": "boolean" }, { "type": "string" }, { "type": "number" } ],
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}

因此,当您只需要两个项目时,您可以引用 my-tuple#closed,当您需要三个项目时,您可以引用 my-tuple#extended

包含

草案 6 中的新增功能

虽然 items 架构必须对数组中的每个项目有效,但 contains 架构只需要对数组中的一个或多个项目进行验证。

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

一个 "number" 就足以通过这个测试

数据
["life", "universe", "everything", 42]
符合模式

但是如果我们没有数字,它就会失败

数据
["life", "universe", "everything", "forty-two"]
不符合模式

当然,全是数字也是可以的

数据
[1, 2, 3, 4, 5]
符合模式

minContains / maxContains

2019-09 草案新增内容

minContainsmaxContains 可以与 contains 结合使用,以进一步指定模式匹配 contains 约束的次数。这些关键字可以是任何非负数,包括零。

模式
{ "type": "array", "contains": { "type": "number" }, "minContains": 2, "maxContains": 3}

失败 minContains

数据
["apple", "orange", 2]
不符合模式
数据
["apple", "orange", 2, 4]
符合模式
数据
["apple", "orange", 2, 4, 8]
符合模式

失败 maxContains

数据
["apple", "orange", 2, 4, 8, 16]
不符合模式

长度

可以使用 minItemsmaxItems 关键字指定数组的长度。 每个关键字的值必须是非负数。 这些关键字在进行 列表验证元组验证 时都可以使用。

模式
{ "type": "array", "minItems": 2, "maxItems": 3}
数据
[]
不符合模式
数据
[1]
不符合模式
数据
[1, 2]
符合模式
数据
[1, 2, 3]
符合模式
数据
[1, 2, 3, 4]
不符合模式

唯一性

架构可以确保数组中的每个项目都是唯一的。只需将 uniqueItems 关键字设置为 true

模式
{ "type": "array", "uniqueItems": true}
数据
[1, 2, 3, 4, 5]
符合模式
数据
[1, 2, 3, 3, 4]
不符合模式

空数组始终通过

数据
[]
符合模式

需要帮助?

您觉得这些文档有用吗?

帮助我们使我们的文档更棒!

在 JSON Schema,我们像对待其他类型贡献一样重视文档贡献!

仍然需要帮助?

学习 JSON Schema 通常很令人困惑,但别担心,我们在这里提供帮助!。