大家好,提前致谢。
我正在尝试创建一个 JSON 模式来强制数组包含一个 A 和 B 对象以及 N 个 C 对象,其中 A 和 B 是 C 对象,N 是介于 0 和无穷大之间的整数。
因此:
[A, B]
[A, B, C1]
[A, B, C1, .., CN]
都是有效,不过:
[A]
[A, C1]
[A, C1, .., CN]
无效。
为了明确起见,A 和 B 必须在场。 C 对象是可选的,但您可以拥有任意数量的对象。
C 对象模式:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "C Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
}
因此,C 对象是仅包含属性“id”和“name”的任何有效 JSON 对象,其中“id”是整数,“name”是字符串。
A 和 B 对象模式:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "A Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"enum": ["A"]
}
},
"additionalProperties": false
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "B Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"enum": ["B"]
}
},
"additionalProperties": false
}
A 和 B 对象与 C 对象的不同之处在于强制执行名称值。 A 对象的 name 值必须是字段 enum 中包含的值,其中 enum 包含单个值。
迄今为止我最完整的架构是:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "To Date Solution",
"description": "So far this is the most complete attempt at enforcing values to be contained within a JSON structure using JSON schemas.",
"type": "array"
"items": {
"allOf": [
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "C Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
}
]
}
}
这强制其中包含的所有对象都必须是 C 类型,即 A 和 B 的类型,尽管我不确定如何强制在我的数组中至少包含 A 和 B 的单个实例。
您正在寻找的称为“元组类型”。
如果
items
关键字的值为数组,则数组数据中的项必须与相应位置的模式匹配。 其他项目(最后一个索引之后)与 additionalItems
匹配(或者如果 additionalItems
是 false
,则不允许)。
所以,大致你想要的是这样的:
{
"type": "array",
"items": [
{"$ref": "#/definitions/itemTypeA"},
{"$ref": "#/definitions/itemTypeB"}
],
"additionalItems": {"$ref": "#/definitions/itemTypeC"},
"definitions": {
... actual definitions for A/B/C ...
}
}
如果您想确保 A 和 B 存在,那么您只需使用
minItems
指定最小长度,因此至少有两项(由于“元组类型”,必须与 A 和 B 匹配) .
(这还假设 A 和 B 是数组中的第一项。如果这不是您想要的,那么它会变得有点复杂 - 尽管为 v5 建议了一个
contains
关键字来处理这个问题整齐地。)
更详细的现场演示:
我已经确定了一个解决我的问题的解决方案,强制 A 和 B 出现在数组中,尽管是按位置执行的,因此需要我正在验证的 JSON 对象以某种方式排序。
工作架构
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Order dependent solution",
"type": "array",
"items": [
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "A Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"enum": ["A"]
}
},
"additionalProperties": false
},
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "B Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string",
"enum": ["B"]
}
},
"additionalProperties": false
}
],
"additionalItems": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "C Object",
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"additionalProperties": false
}
}
此 JSON 模式验证一个 JSON 数组,其中包含索引 0 处的 A 对象、索引 1 处的 B 对象以及组成所有剩余元素的 C 对象。该解决方案是可用的,并且允许我继续开发,尽管更喜欢独立于订单的解决方案。
如有任何帮助,我们将不胜感激! :)
PS - 这些模式没有优化,并且表现出冗余,我将在最终版本中通过使用“id”和“$ref”关键字删除这些冗余。