问题1.我正在尝试实现这种条件:如果存在一个特殊属性,则需要另一个属性,但是如果不存在,则不需要另一个属性 问题2.在json模式中,我们可以不依赖使用吗? 这是一个示例架构
var schema = {
"properties": {
"smaller": {
"type": "number"
},
"larger": { "type": "number" },
"medium":{'type':'string'},
"bulky":{'type':'string'}
},
require:['smaller','larger'],
additionalProperties:false
};
如果“中等”则要求“大”,否则不需要大。 这里的“不需要”表示如果“中等”不存在,那么笨重的“一定不能存在”
答案 0 :(得分:5)
即使不使用JSON Schema draft-07 if-then-else ,也有几种方法可以达到要求的效果。
此处的逻辑含义:如果存在“中”,则要求“大” 可以翻译为“中”,或者“要求”“大” (后者表示存在“ medium” ),可以进一步详细说明为“ 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 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”-XOR,“ allOf”-AND,“ not”-取反,但请注意规范:
如果实例无法针对此关键字定义的架构成功验证,则该实例对该关键字有效。
最明显。我不确定您是否在问题中排除了这一点,因此以防万一。请注意,如果您不想简单地限制有效密钥,则可以使用“ 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
在评论中澄清后:
第6草案-这里的“不需要”表示如果“中等”不存在,那么笨重的“一定不能存在”
“不得”是指防止体积大。
我将重述您的病情:
1。如果“中”存在,则“大”必须存在->两个密钥必须同时存在
2。如果“中”不存在,则“大” 也不能存在->两个键一定不能同时存在
是否可以存在“庞大”而“中等”不存在?
不。请参阅2。反之亦然(请参阅1.)。布尔等式(与逻辑XOR互补)。
因此,如果“大量”存在-则意味着“中等”必须始终存在...这意味着两者都是必需,或者都不需要(甚至不允许) / em>。
因为它是草案06,所以您还可以使用“ propertyNames” 来定义允许的属性名称(这种逻辑的捷径)。
翻译为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"] } },
]
}
]
异或-(两者都是必需的)或(不需要介质,不需要体积大的)。
请注意,我没有执行“ not”:{“ required”:[“ medium”,“ bulky”]} ,因为只有这些键之一存在时,“ required”模式才会失败,表示“不”将返回成功的验证结果。需要使用de Morgans法来重新定义它:
"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",
},
]
}
它能回答您的问题吗?
答案 1 :(得分:2)
JSON Schema Draft-07已包含these new keywords if
,then
和else
,它们使您可以使用条件模式。
在此示例中:
foo
属性foo
设置为"bar"
,则bar
属性也将成为必填项
var ajv = new Ajv({
allErrors: true
});
var schema = {
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "string"
},
},
"required": ["foo"],
"if": {
"properties": {
"foo": {
"enum": ["bar"]
}
}
},
"then": {
"required": ["bar"]
}
}
var validate = ajv.compile(schema);
test({
"foo": "bar",
"bar": "baz"
}); // VALID
test({
"foo": "xyz"
}); // VALID
test({
"foo": "bar",
}); // NOT VALID
function test(data) {
var valid = validate(data);
if (valid) console.log('VALID', data);
else console.log('NOT VALID', data);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/6.5.5/ajv.min.js"></script>
希望这是有道理的,您可以相应地修改代码。
PS:在您的模式中,您具有require
属性,但我不确定这是有效的JSON Schema关键字。您可能是用required
来代替的。
答案 2 :(得分:0)
如果您有多个依赖于各自值的属性,则可以使用属性依赖项。
{
"type": "object",
"properties": {
"weight_1": {
"type": "integer"
},
"weight_2": {
"type": "integer"
},
"description_1": {
"type": "string"
},
"description_2": {
"type": "string"
}
},
"allOf": [
{
"if": {
"properties": {
"weight_1": {
"minimum": 10
}
}
},
"then": {
"dependencies": {
"weight_1": ["description_1"]
}
}
},
{
"if": {
"properties": {
"weight_2": {
"minimum": 100
}
}
},
"then": {
"dependencies": {
"weight_2": ["description_2"]
}
}
}
]
}