我有这个字段
assignments
:
chapters
在赋值对象中是可选的。type
为必填项。multi
时:
pointer
值应该存在于每个 chapters
对象中,如果其assignments
对象的一部分。notes
时:
pointer
是必需的,除非 completed
为真。{
"assignments": [
{
"type": "multi",
"pointer": "1",
"chapters": [
{
"id": "203"
},
{
"id": "204"
}
]
},
{
"type": "multi",
"chapters": [
{
"id": "201",
"pointer": "3"
},
{
"id": "202",
"pointer": "3"
}
]
},
{
"type": "notes",
"pointer": "4"
},
{
"type": "notes",
"completed": true
}
]
}
为了使用 json-schema.org/draft-04 验证此架构,我不确定如何满足嵌套依赖项的所有条件。我已经尝试了以下模式,但它没有按预期工作。 由于验证
pointer
的预期完成为 false,因此 completed
是可选的,并且仅在必须设置为 true
时才会出现。对于类型 multi
,当 pointer
是 pointer
的一部分时,期望 chapters
出现。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"assignments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["multi", "notes"]
},
"pointer": {
"type": "string"
},
"completed": {
"type": "boolean"
},
"chapters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"pointer": {
"type": "string"
}
},
"required": ["id"]
}
}
},
"required": ["type"],
"dependencies": {
"type": {
"oneOf": [
{
"properties": {
"type": { "enum": ["multi"] }
},
"oneOf": [
{
"properties": {
"pointer": { "type": "string" }
}
},
{
"properties": {
"chapters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"pointer": { "type": "string" }
},
"required": ["pointer"]
}
}
}
}
]
},
{
"properties": {
"type": { "enum": ["notes"] },
"completed": { "enum": [true] }
}
},
{
"properties": {
"type": { "enum": ["notes"] }
},
"required": ["pointer"]
}
]
}
}
}
}
},
"required": ["assignments"]
}
示例:
{
"assignments": [
{
"type": "notes",
"completed": true
}
]
}
{
"assignments": [
{
"type": "notes",
"pointer": "4"
}
]
}
notes is not a valid enum value,#/assignments/0: #: 2 subschemas matched instead of one
{
"assignments": [
{
"type": "notes"
}
]
}
{
"assignments": [
{
"type": "multi",
"chapters": [
{
"id": "201",
"pointer": "3"
},
{
"id": "202",
"pointer": "3"
}
]
}
]
}
{
"assignments": [
{
"type": "multi",
"pointer": "4",
"chapters": [
{
"id": "201"
},
{
"id": "202"
}
]
}
]
}
multi is not a valid enum value,#/assignments/0: #: 2 subschemas matched instead of one, multi is not a valid enum value,#/assignments/0: required key [pointer] not found
{
"assignments": [
{
"type": "multi",
"chapters": [
{
"id": "201",
"pointer": "4"
},
{
"id": "202",
"pointer": "4"
}
]
}
]
}
{
"assignments": [
{
"type": "multi",
"chapters": [
{
"id": "201",
"pointer": "4"
},
{
"id": "202"
}
]
}
]
}
pointer
应该出现在“章节”数组之外,或者应该是每个“章节”对象的一部分)不幸的是,draft-04 需要一个大而冗长的模式来实现条件行为。
这在 Draft-07 或更新版本中更加清晰。
我已将每个条件模块化在
definitions
条目中,然后使用 oneOf
来引用每个条件。错误输出非常详细,因为它需要报告评估过程中的每一个失败。
这里需要考虑的几件事是以下用例:
type: notes
和 completed
未涵盖。无法评估缺少的关键字。pointer
对父母或孩子有效,而不是两者都有效。所以这件事正如我所想的那样通过了。{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [
"assignments"
],
"properties": {
"assignments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {},
"pointer": {
"type": "string"
},
"completed": {
"type": "boolean"
},
"chapters": {
"type": "array",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
},
"pointer": {
"type": "string"
}
}
}
}
},
"oneOf": [
{
"$ref": "#/definitions/multi-pointer-in-child"
},
{
"$ref": "#/definitions/multi-pointer-at-root"
},
{
"$ref": "#/definitions/notes-completed:false"
},
{
"$ref": "#/definitions/notes-completed:true"
}
]
}
}
},
"definitions": {
"multi-pointer-in-child": {
"properties": {
"type": {
"enum": [
"multi"
]
},
"chapters": {
"minItems": 1,
"items": {
"required": [
"pointer"
]
}
},
"completed": {}
},
"required": [
"type"
],
"not": {
"required": [
"pointer"
]
},
"additionalProperties": false
},
"multi-pointer-at-root": {
"properties": {
"type": {
"enum": [
"multi"
]
},
"pointer": {},
"chapters": {
"items": {
"not": {
"required": [
"pointer"
]
}
}
},
"completed": {}
},
"required": [
"type"
],
"additionalProperties": false
},
"notes-completed:false": {
"additionalProperties": false,
"properties": {
"type": {
"enum": [
"notes"
]
},
"chapters": {},
"completed": {
"enum": [
false
]
},
"pointer": {}
},
"required": [
"type",
"pointer"
]
},
"notes-completed:true": {
"additionalProperties": false,
"properties": {
"type": {
"enum": [
"notes"
]
},
"chapters": {},
"completed": {
"enum": [
true
]
}
},
"required": [
"type"
],
"not": {
"required": [
"pointer"
]
}
}
}
}