即使不使用 JSON Schema Draft-07 if-then-else,也有几种方法可以达到所需的效果。
逻辑运算符和含义(draft-04 及以上)
这里有一个逻辑含义:如果存在“中等”,则需要“庞大”可以翻译为不存在“中等”或“庞大”是“需要”(后者暗示存在“中等”),可以进一步阐述为“ medium”不需要或“bulky”是“required”(因为如果“medium”存在,它将满足需要的条件)。请参见下面的架构:
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [
{
"not" : { "required" : ["medium"] }
},
{
"required" : ["bulky"]
}
],
"additionalProperties" : false
在这里查看以供参考:
JSON 模式 - 如果对象*不*包含特定属性则有效
http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7
“anyOf” - 逻辑 OR,“oneOf” - XOR,“allOf” - AND,“not” - 否定,但请注意规范:
如果实例未能针对此关键字定义的模式成功验证,则该实例对该关键字有效。
Draft-06 - 依赖项 + propertyNames
最明显的。我不确定您是否在问题中排除了这个问题,所以放在这里以防万一。请注意,如果您不想简单地限制有效键,则可以使用“propertyNames”而不是“additionalProperties”(实际上就是添加它的目的)。
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"dependencies" : {
"medium" : ["bulky"]
},
"propertyNames" : {
"enum" : [
"smaller",
"larger",
"medium",
"bulky"
]
}
在这里查看参考:http: //json-schema.org/latest/json-schema-validation.html#rfc.section.6.5.7
更新
在评论中澄清后:
对于draft-6 - 这里的“不需要”意味着如果“中等”不存在,那么笨重的“一定不能存在”
“不得”是指防止出现笨重的东西。
我将改写你的条件:
1. 如果“medium”存在,“bulky”必须存在 -> 两个键必须同时存在
2. 如果“medium”不存在,“bulky”也不能出现 -> 两个键不能同时出现
“大”可以存在而“中”不存在吗?
不。见 2。反之亦然(见 1)。布尔相等(与逻辑 XOR 互补)。
因此,如果“笨重”存在 - 这意味着“中等”必须始终存在......这意味着两者都是必需的或两者都不能被要求(甚至不允许)。
由于它是草案 06,您还可以使用“propertyNames”来定义允许的属性名称(这种逻辑的一种快捷方式)。
逻辑运算符和含义(draft-06 及更高版本)
转换为 JSOn Schema 的正确逻辑操作如下所示:
"oneOf" : [
{ "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
{
"allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
{"not" : { "required" : ["medium"] } },
{"not" : { "required" : ["bulky"] } },
]
}
]
一个 XOR - 要么(两者都需要)要么(不需要中等且不需要庞大)。
请注意我没有做"not" : { "required" : ["medium","bulky"] }因为当只有其中一个键存在时,"required" 模式将失败,这意味着 "not" 将成功返回验证结果。需要使用德摩根定律重新表述它:
"oneOf" : [
{ "required" : ["medium","bulky"] },
{
"not" : { <=== !medium ^ !bulky = !(medium v bulky)
"anyOf" : [
{ "required" : ["medium"] },
{ "required" : ["bulky"] },
]
}
}
]
但是,使用“propertyNames”也可以解决问题。请参阅以下架构:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [
{
"required" : ["medium","bulky"]
},
{
"propertyNames" : {
"enum" : [
"smaller",
"larger"
]
},
}
],
"examples" : [
{
"smaller" : 1,
"larger" : 2,
},
{
"smaller" : 1,
"larger" : 2,
"bulky" : "test",
"medium" : ""
},
{
"smaller" : 1,
"larger" : 2,
"medium" : ""
},
{
"smaller" : 1,
"larger" : 2,
"bulky" : "test",
},
]
}
它回答了你的问题吗?