如何在不同的属性类型上使用 anyOf?
How to use anyOf on different properties type?
在下面的架构中,我需要 items_list
、price
和 variance
作为必需的键。条件是 price
和 variance
可以为 null 也可以不为 null 但两者不能为 null。
虽然我能够实现它,但我很期待是否有任何更短的方法来做到这一点。另外,我不确定 required
和 additionalProperties
键的确切位置。
非常感谢任何帮助。
{
"type": "object",
"properties": {
"items_list": {
"type": "array",
"items": {
"type": "string"
}
},
},
"anyOf": [
{
"properties": {
"price": {
"type": "number",
"minimum": 0,
},
"variance": {
"type": [
"number",
"null"
],
"minimum": 0,
},
},
},
{
"properties": {
"price": {
"type": [
"number",
"null"
],
"minimum": 0,
},
"variance": {
"type": "number",
"minimum": 0,
},
},
},
],
# "required": [
# "items_list",
# "price",
# "variance",
# ],
# "additionalProperties": False,
}
看来您的判断基本正确。这是放置 required
.
的正确位置
使用additionalProperties: false
,你还需要在顶层定义properties
,additionalProperties
不能"see through" *Of
关键字(applicators)
您可以添加 properties: [prop] : true
,但定义所有属性。
您需要这样做,因为 additionalProperties
只知道同一级别的同一架构对象中的 properties
。
回答问题"can it be shorter?",答案是肯定的。一般的经验法则是永远不要 define 布尔逻辑关键字中的任何内容。仅使用布尔逻辑关键字来添加复合约束。我使用术语 "compound constraint" 表示基于模式中多个值的约束。在这种情况下,复合约束是价格和方差不能都为空。
{
"type": "object",
"properties": {
"items_list": {
"type": "array",
"items": { "type": "string" }
},
"price": { "type": ["number", "null"], "minimum": 0 },
"variance": { "type": ["number", "null" ], "minimum": 0 }
},
"required": ["items_list", "price", "variance"],
"additionalProperties": false,
"allOf": [{ "$ref": "#/definitions/both-price-and-variance-cannot-be-null" }],
"definitions": {
"both-price-and-variance-cannot-be-null": {
"not": {
"properties": {
"price": { "type": "null" },
"variance": { "type": "null" }
},
"required": ["price", "variance"]
}
}
}
}
您不仅不必为了 additionalProperties
的正常工作而费尽心思,而且更易于阅读。它甚至符合您对问题的描述,"price and variance may or may not be null" (properties
) 但 "both cannot be null" (not
(复合约束))。您可以通过内联定义使其更短,但我将其包括在内是为了展示这种技术的表现力,同时仍然比原始模式更短。
在下面的架构中,我需要 items_list
、price
和 variance
作为必需的键。条件是 price
和 variance
可以为 null 也可以不为 null 但两者不能为 null。
虽然我能够实现它,但我很期待是否有任何更短的方法来做到这一点。另外,我不确定 required
和 additionalProperties
键的确切位置。
非常感谢任何帮助。
{
"type": "object",
"properties": {
"items_list": {
"type": "array",
"items": {
"type": "string"
}
},
},
"anyOf": [
{
"properties": {
"price": {
"type": "number",
"minimum": 0,
},
"variance": {
"type": [
"number",
"null"
],
"minimum": 0,
},
},
},
{
"properties": {
"price": {
"type": [
"number",
"null"
],
"minimum": 0,
},
"variance": {
"type": "number",
"minimum": 0,
},
},
},
],
# "required": [
# "items_list",
# "price",
# "variance",
# ],
# "additionalProperties": False,
}
看来您的判断基本正确。这是放置 required
.
使用additionalProperties: false
,你还需要在顶层定义properties
,additionalProperties
不能"see through" *Of
关键字(applicators)
您可以添加 properties: [prop] : true
,但定义所有属性。
您需要这样做,因为 additionalProperties
只知道同一级别的同一架构对象中的 properties
。
回答问题"can it be shorter?",答案是肯定的。一般的经验法则是永远不要 define 布尔逻辑关键字中的任何内容。仅使用布尔逻辑关键字来添加复合约束。我使用术语 "compound constraint" 表示基于模式中多个值的约束。在这种情况下,复合约束是价格和方差不能都为空。
{
"type": "object",
"properties": {
"items_list": {
"type": "array",
"items": { "type": "string" }
},
"price": { "type": ["number", "null"], "minimum": 0 },
"variance": { "type": ["number", "null" ], "minimum": 0 }
},
"required": ["items_list", "price", "variance"],
"additionalProperties": false,
"allOf": [{ "$ref": "#/definitions/both-price-and-variance-cannot-be-null" }],
"definitions": {
"both-price-and-variance-cannot-be-null": {
"not": {
"properties": {
"price": { "type": "null" },
"variance": { "type": "null" }
},
"required": ["price", "variance"]
}
}
}
}
您不仅不必为了 additionalProperties
的正常工作而费尽心思,而且更易于阅读。它甚至符合您对问题的描述,"price and variance may or may not be null" (properties
) 但 "both cannot be null" (not
(复合约束))。您可以通过内联定义使其更短,但我将其包括在内是为了展示这种技术的表现力,同时仍然比原始模式更短。