参考
数组
数组用于有序元素。在 JSON 中,数组中的每个元素都可能是不同类型。
在 Python 中,"array" 等同于 list
或 tuple
类型,具体取决于使用情况。但是,Python 标准库中的 json
模块始终使用 Python 列表来表示 JSON 数组。
JSON 中通常有两种使用数组的方式
- 列表验证:任意长度的序列,其中每个项目都匹配相同的 模式.
- 元组验证:固定长度的序列,其中每个项目可能具有不同的模式。在此用法中,每个项目的索引(或位置)对于解释值的方式具有重要意义。(此用法通常在某些编程语言中被赋予一个完全独立的类型,例如 Python 的
tuple
)。
项目
列表验证对于任意长度的数组很有用,其中每个项目都匹配相同的模式。对于这种数组,设置 items
关键字 为单个模式,该模式将用于验证数组中的所有项目。
在以下示例中,我们定义数组中的每个项目都是一个数字
单个“非数字”会导致整个数组无效
空数组始终有效
元组验证
元组验证在数组是项目集合时很有用,其中每个项目都有不同的模式,并且每个项目的序数索引是有意义的。
例如,您可以将街道地址(例如 1600 Pennsylvania Avenue NW
)表示为以下形式的 4 元组
[number, street_name, street_type, direction]
这些字段中的每一个都将具有不同的模式
number
: 地址编号。必须是数字。street_name
: 街道名称。必须是字符串。street_type
: 街道类型。应为来自固定值集的字符串。direction
: 地址的城市象限。应为来自不同值集的字符串。
为此,我们使用 prefixItems
关键字。 prefixItems
是一个数组,其中每个项目都是与文档数组的每个索引相对应的模式。也就是说,一个数组,其中第一个元素验证输入数组的第一个元素,第二个元素验证输入数组的第二个元素,等等。
items
关键字的替代形式处理。当 items
是一个模式数组而不是单个模式时,它会像 prefixItems
的行为一样。这是示例模式
"Drive" 不是可接受的街道类型之一
此地址缺少街道号码
可以不提供所有项目
并且,默认情况下,也可以在末尾添加其他项目
附加项目
关键字 items
可用于控制在元组中是否允许在 prefixItems
定义之外添加其他项目。关键字 items
的值是一个模式,所有额外的项目都必须通过该模式才能通过关键字验证。
additionalItems
来约束元组上的额外项目。它的工作原理与 items
相同,只是名称发生了改变。items
,则关键字 additionalItems
将被忽略。这里,我们将重用上面的示例模式,但将 items
设置为 false
,这将禁止元组中的额外项目。
可以不提供所有项目
但是,由于 items
为 false
,我们无法提供额外的项目
您可以使用非布尔模式来约束额外项目可以具有的值,以表达更复杂的约束。在这种情况下,我们可以说额外项目是允许的,只要它们都是字符串。
额外的字符串项目是可以接受的...
... 但是其他任何内容都不可以
未评估项目
在想要添加或禁止数组中的额外项目时,unevaluatedItems
关键字非常有用。
unevaluatedItems
应用于任何未被 items
、prefixItems
或 contains
关键字评估的值。正如 unevaluatedProperties
只影响对象中的 属性,unevaluatedItems
只影响数组中的 项目。
注意!“未评估”并不意味着“未被 items
、prefixItems
或 contains
评估”。“未评估”意味着“未成功评估”或“评估结果不为真”。
就像 items
一样,如果您将 unevaluatedItems
设置为 false
,您可以禁止数组中出现额外的项目。
这里,所有值都被评估。模式通过验证。
但在这里,模式验证失败,因为 "unevaluatedItems": false
指定不应存在额外的值。
请注意,items
不会“查看” 实例 中的 allOf
、anyOf
或 oneOf
,这些实例位于同一 子模式 中。因此,在这个下一个例子中,items
忽略 allOf
,因此无法进行验证。
但是,如果你用 unevaluatedItems
替换 items
,那么同一个数组就可以验证。
你也可以创建一个“半闭合”的模式:当你想保留前两个参数,但在某些情况下又需要添加更多参数时,这种模式非常有用。(在某些情况下,对两个参数是“闭合”的,但在你需要的时候,对更多参数是“开放”的。)
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}
此处,模式被“封闭”到两个数组项。 之后,您可以使用 $ref
添加另一个项,如下所示
"$defs": { "closed": { "$anchor": "closed", "$ref": "#", "unevaluatedItems": false } }}
因此,当您只需要两个项目时,您可以引用 my-tuple#closed
,当您需要三个项目时,您可以引用 my-tuple#extended
。
包含
虽然 items
架构必须对数组中的每个项目有效,但 contains
架构只需要对数组中的一个或多个项目进行验证。
一个 "number" 就足以通过这个测试
但是如果我们没有数字,它就会失败
当然,全是数字也是可以的
minContains / maxContains
minContains
和 maxContains
可以与 contains
结合使用,以进一步指定模式匹配 contains
约束的次数。这些关键字可以是任何非负数,包括零。
失败 minContains
失败 maxContains
长度
可以使用 minItems
和 maxItems
关键字指定数组的长度。 每个关键字的值必须是非负数。 这些关键字在进行 列表验证 或 元组验证 时都可以使用。
唯一性
架构可以确保数组中的每个项目都是唯一的。只需将 uniqueItems
关键字设置为 true
。
空数组始终通过