如何仅在其他不存在时允许 属性 并允许 json 模式中的任何其他属性
How to allow one property only if other is not present and allow any of other propeties in json schema
我有六个属性:姓名、年龄、phone、deletePhone、地址、deleteAddress。
我想创建允许上述任何属性的架构,但 phone 不应与 deletePhone 一起出现,地址不应与 deleteAddress 一起出现(反之亦然)。
我试过这个模式:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
},
"phone": {
"type": "number"
},
"deletePhone": {
"type": "boolean"
},
"address": {
"type": "string"
},
"deleteAddress": {
"type": "boolean"
}
},
"allOf": [
{
"oneOf": [
{
"required": ["phone"]
},
{
"required": ["deletePhone"]
}
]
},
{
"oneOf": [
{
"required": ["address"]
},
{
"required": ["deleteAddress"]
}
]
}
]
}
验证为真
{
"name": "my name",
"address": "some addr",
"phone": 34
}
并为
验证错误
{
"address": "some addr",
"phone": 34,
"deletePhone": true
}
这是正确的,但它也为
验证了错误
{
"phone": 34
}
or
{
"name": "some name"
}
我想验证哪个是真的,我知道我缺少 anyOf、oneOf 的一些组合,或者有更好的方法吗?
编辑: 一种不同但更可靠和紧凑的方法。
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"},
"phone": {"type": "number"},
"deletePhone": {"type": "boolean"},
"address": {"type": "string"},
"deleteAddress": {"type": "boolean"}
},
"additionalProperties": false,
"allOf": [
{
"oneOf": [
{
"allOf": [
{"required": ["phone"]},
{"not":{"required":["deletePhone"]}}
]
},
{
"allOf": [
{"required": ["deletePhone"]},
{"not":{"required":["phone"]}}
]
},
{
"allOf": [
{"not":{"required": ["deletePhone"]}},
{"not":{"required":["phone"]}}
]
}
]
},
{
"oneOf": [
{
"allOf": [
{"required": ["address"]},
{"not":{"required":["deleteAddress"]}}
]
},
{
"allOf": [
{"required": ["deleteAddress"]},
{"not":{"required":["address"]}}
]
},
{
"allOf": [
{"not":{"required": ["deleteAddress"]}},
{"not":{"required":["address"]}}
]
}
]
}
]
}
测试 ajv
:https://runkit.com/embed/5qwkquyweir2
OLD(不工作):
如果您可以允许 null
值等于 属性 不存在,架构可能会如此简单:
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
},
"allOf": [
{
"oneOf": [
{
"properties": {
"phone": {"type": "number"},
"deletePhone": {"type": "null"}
},
"required": ["phone"]
},
{
"properties": {
"phone": {"type": "null"},
"deletePhone": {"type": "boolean"}
},
"required": ["deletePhone"]
},
{}
]
},
{
"oneOf": [
{
"properties": {
"address": {"type": "string"},
"deleteAddress": {"type": "null"}
},
"required": ["address"]
},
{
"properties": {
"address": {"type": "null"},
"deleteAddress": {"type": "boolean"}
},
"required": ["deleteAddress"]
},
{}
]
}
]
}
但如果不能允许{"deletePhone":null,"phone":123}
schema 比较复杂和重复:
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
},
"allOf": [
{
"oneOf": [
{
"properties": {
"name": {},
"age": {},
"address": {},
"deleteAddress": {},
"phone": {"type": "number"}
},
"required": ["phone"],
"additionalProperties": false
},
{
"properties": {
"name": {},
"age": {},
"address": {},
"deleteAddress": {},
"deletePhone": {"type": "boolean"}
},
"required": ["deletePhone"],
"additionalProperties": false
},
{}
]
},
{
"oneOf": [
{
"properties": {
"name": {},
"age": {},
"phone": {},
"deletePhone": {},
"address": {"type": "string"}
},
"required": ["address"],
"additionalProperties": false
},
{
"properties": {
"name": {},
"age": {},
"phone": {},
"deletePhone": {},
"deleteAddress": {"type": "boolean"}
},
"required": ["deleteAddress"],
"additionalProperties": false
},
{}
]
}
]
}
下面的模式适用于所有情况,但它很长。
{
"type": "object",
"oneOf": [
{
"anyOf": [
{
"oneOf": [
{
"properties": {
"phone": {
"type": "number"
},
"address": {
"type": "string"
},
"deleteAddress": {
"type": "boolean"
}
},
"required": [
"phone"
],
"not": {
"required": [
"deletePhone"
]
}
},
{
"properties": {
"deletePhone": {
"type": "boolean"
},
"address": {
"type": "string"
},
"deleteAddress": {
"type": "boolean"
}
},
"required": [
"deletePhone"
],
"not": {
"required": [
"phone"
]
}
},
{
"oneOf": [
{
"required": [
"phone",
"address",
"deleteAddress"
]
},
{
"required": [
"deletePhone",
"address",
"deleteAddress"
]
}
]
}
]
},
{
"oneOf": [
{
"properties": {
"address": {
"type": "string"
},
"phone": {
"type": "number"
},
"deletePhone": {
"type": "boolean"
}
},
"required": [
"address"
],
"not": {
"required": [
"deleteAddress"
]
}
},
{
"properties": {
"deleteAddress": {
"type": "boolean"
},
"phone": {
"type": "number"
},
"deletePhone": {
"type": "boolean"
}
},
"required": [
"deleteAddress"
],
"not": {
"required": [
"address"
]
}
},
{
"oneOf": [
{
"required": [
"address",
"phone",
"deletePhone"
]
},
{
"required": [
"deleteAddress",
"phone",
"deletePhone"
]
}
]
}
]
}
]
},
{
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
},
"additionalProperties": false
}
]
}
我认为这是最简单的解决方案。
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" },
"phone": { "type": "number" },
"deletePhone": { "type": "boolean" },
"address": { "type": "string" },
"deleteAddress": { "type": "boolean" }
},
"allOf": [
{ "not": { "required": ["phone", "deletePhone"] } },
{ "not": { "required": ["address", "deleteAddress"] } }
]
}
我有六个属性:姓名、年龄、phone、deletePhone、地址、deleteAddress。
我想创建允许上述任何属性的架构,但 phone 不应与 deletePhone 一起出现,地址不应与 deleteAddress 一起出现(反之亦然)。
我试过这个模式:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
},
"phone": {
"type": "number"
},
"deletePhone": {
"type": "boolean"
},
"address": {
"type": "string"
},
"deleteAddress": {
"type": "boolean"
}
},
"allOf": [
{
"oneOf": [
{
"required": ["phone"]
},
{
"required": ["deletePhone"]
}
]
},
{
"oneOf": [
{
"required": ["address"]
},
{
"required": ["deleteAddress"]
}
]
}
]
}
验证为真
{
"name": "my name",
"address": "some addr",
"phone": 34
}
并为
验证错误{
"address": "some addr",
"phone": 34,
"deletePhone": true
}
这是正确的,但它也为
验证了错误{
"phone": 34
}
or
{
"name": "some name"
}
我想验证哪个是真的,我知道我缺少 anyOf、oneOf 的一些组合,或者有更好的方法吗?
编辑: 一种不同但更可靠和紧凑的方法。
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"},
"phone": {"type": "number"},
"deletePhone": {"type": "boolean"},
"address": {"type": "string"},
"deleteAddress": {"type": "boolean"}
},
"additionalProperties": false,
"allOf": [
{
"oneOf": [
{
"allOf": [
{"required": ["phone"]},
{"not":{"required":["deletePhone"]}}
]
},
{
"allOf": [
{"required": ["deletePhone"]},
{"not":{"required":["phone"]}}
]
},
{
"allOf": [
{"not":{"required": ["deletePhone"]}},
{"not":{"required":["phone"]}}
]
}
]
},
{
"oneOf": [
{
"allOf": [
{"required": ["address"]},
{"not":{"required":["deleteAddress"]}}
]
},
{
"allOf": [
{"required": ["deleteAddress"]},
{"not":{"required":["address"]}}
]
},
{
"allOf": [
{"not":{"required": ["deleteAddress"]}},
{"not":{"required":["address"]}}
]
}
]
}
]
}
测试 ajv
:https://runkit.com/embed/5qwkquyweir2
OLD(不工作):
如果您可以允许 null
值等于 属性 不存在,架构可能会如此简单:
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
},
"allOf": [
{
"oneOf": [
{
"properties": {
"phone": {"type": "number"},
"deletePhone": {"type": "null"}
},
"required": ["phone"]
},
{
"properties": {
"phone": {"type": "null"},
"deletePhone": {"type": "boolean"}
},
"required": ["deletePhone"]
},
{}
]
},
{
"oneOf": [
{
"properties": {
"address": {"type": "string"},
"deleteAddress": {"type": "null"}
},
"required": ["address"]
},
{
"properties": {
"address": {"type": "null"},
"deleteAddress": {"type": "boolean"}
},
"required": ["deleteAddress"]
},
{}
]
}
]
}
但如果不能允许{"deletePhone":null,"phone":123}
schema 比较复杂和重复:
{
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
},
"allOf": [
{
"oneOf": [
{
"properties": {
"name": {},
"age": {},
"address": {},
"deleteAddress": {},
"phone": {"type": "number"}
},
"required": ["phone"],
"additionalProperties": false
},
{
"properties": {
"name": {},
"age": {},
"address": {},
"deleteAddress": {},
"deletePhone": {"type": "boolean"}
},
"required": ["deletePhone"],
"additionalProperties": false
},
{}
]
},
{
"oneOf": [
{
"properties": {
"name": {},
"age": {},
"phone": {},
"deletePhone": {},
"address": {"type": "string"}
},
"required": ["address"],
"additionalProperties": false
},
{
"properties": {
"name": {},
"age": {},
"phone": {},
"deletePhone": {},
"deleteAddress": {"type": "boolean"}
},
"required": ["deleteAddress"],
"additionalProperties": false
},
{}
]
}
]
}
下面的模式适用于所有情况,但它很长。
{
"type": "object",
"oneOf": [
{
"anyOf": [
{
"oneOf": [
{
"properties": {
"phone": {
"type": "number"
},
"address": {
"type": "string"
},
"deleteAddress": {
"type": "boolean"
}
},
"required": [
"phone"
],
"not": {
"required": [
"deletePhone"
]
}
},
{
"properties": {
"deletePhone": {
"type": "boolean"
},
"address": {
"type": "string"
},
"deleteAddress": {
"type": "boolean"
}
},
"required": [
"deletePhone"
],
"not": {
"required": [
"phone"
]
}
},
{
"oneOf": [
{
"required": [
"phone",
"address",
"deleteAddress"
]
},
{
"required": [
"deletePhone",
"address",
"deleteAddress"
]
}
]
}
]
},
{
"oneOf": [
{
"properties": {
"address": {
"type": "string"
},
"phone": {
"type": "number"
},
"deletePhone": {
"type": "boolean"
}
},
"required": [
"address"
],
"not": {
"required": [
"deleteAddress"
]
}
},
{
"properties": {
"deleteAddress": {
"type": "boolean"
},
"phone": {
"type": "number"
},
"deletePhone": {
"type": "boolean"
}
},
"required": [
"deleteAddress"
],
"not": {
"required": [
"address"
]
}
},
{
"oneOf": [
{
"required": [
"address",
"phone",
"deletePhone"
]
},
{
"required": [
"deleteAddress",
"phone",
"deletePhone"
]
}
]
}
]
}
]
},
{
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
},
"additionalProperties": false
}
]
}
我认为这是最简单的解决方案。
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" },
"phone": { "type": "number" },
"deletePhone": { "type": "boolean" },
"address": { "type": "string" },
"deleteAddress": { "type": "boolean" }
},
"allOf": [
{ "not": { "required": ["phone", "deletePhone"] } },
{ "not": { "required": ["address", "deleteAddress"] } }
]
}