根据您的情况,有几种不同的方法。我可以想到四种不同的方法来有条件地要求一个字段。
依赖关系
dependencies 关键字是required 关键字的条件变体。 dependencies 中的 foreach 属性,如果该属性存在于正在验证的 JSON 中,则与该键关联的架构也必须有效。 如果存在“foo”属性,则需要“bar”属性
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"dependencies": {
"foo": { "required": ["bar"] }
}
}
如果架构仅包含 required 关键字,则还有一个短格式。
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"dependencies": {
"foo": ["bar"]
}
}
含义
如果您的条件取决于字段的值,您可以使用称为蕴含的布尔逻辑概念。 “A 蕴含 B”实际上意味着,如果 A 为真,则 B 也必须为真。暗示也可以表示为“!A或B”。 “foo”属性不等于“bar”,或者“bar”属性是必需的。或者换句话说:如果“foo”属性等于“bar”,那么“bar”属性是必需的
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"anyOf": [
{
"not": {
"properties": {
"foo": { "const": "bar" }
},
"required": ["foo"]
}
},
{ "required": ["bar"] }
]
}
如果“foo”不等于“bar”,#/anyOf/0 匹配并且验证成功。如果“foo”等于“bar”,#/anyOf/0 失败,#/anyOf/1 必须有效,anyOf 验证才能成功。
枚举
如果您的条件是基于一个枚举,它会更直接一点。 “foo”可以是“bar”或“baz”。如果“foo”等于“bar”,则需要“bar”。如果“foo”等于“baz”,则需要“baz”。
{
"type": "object",
"properties": {
"foo": { "enum": ["bar", "baz"] },
"bar": { "type": "string" },
"baz": { "type": "string" }
},
"anyOf": [
{
"properties": {
"foo": { "const": "bar" }
},
"required": ["bar"]
},
{
"properties": {
"foo": { "const": "baz" }
},
"required": ["baz"]
}
]
}
如果-那么-否则
JSON Schema (draft-07) 的一个相对较新的添加添加了 if、then 和 else 关键字。 如果“foo”属性等于“bar”,则需要“bar”属性
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"if": {
"properties": {
"foo": { "const": "bar" }
},
"required": ["foo"]
},
"then": { "required": ["bar"] }
}
2017 年 12 月 23 日编辑:更新了暗示部分并添加了 If-Then-Else 部分。
编辑 06/04/2018: 修正 If-Then-Else 并更新单例 enums 以使用 const。