即使不使用 JSON Schema Draft-07 if-then-else,也有几种方法可以达到所需的效果。
逻辑运算符和蕴涵(draft-04 及以上)
这里的逻辑含义:如果存在“中等”,则需要“庞大”可以翻译成不存在“中等”或“庞大”是“必需” (后者暗示 "medium" 存在)可以进一步阐述为 "medium" not required OR "bulky" is "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 schema - valid if object does *not* contain a particular property
http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.7
“anyOf” - 逻辑或,“oneOf” - 异或,“allOf” - 与,“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”不得也存在 -> 两个键不得同时存在
“bulky”可以存在,“medium”不存在吗?
没有。见 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"] } 因为当只有其中一个键存在时,“必需”模式会失败,这意味着“不”将返回成功的验证结果。需要使用德摩根定律重新表述它:
"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",
},
]
}
它回答了你的问题吗?