使用 json-schema 来要求或禁止基于另一个属性值的属性?
Posted
技术标签:
【中文标题】使用 json-schema 来要求或禁止基于另一个属性值的属性?【英文标题】:Use json-schema to require or disallow properties based on another property value? 【发布时间】:2018-10-24 17:49:00 【问题描述】:我要在 json-schema 中完成的工作:当属性 enabled
是 true
时,应该需要某些其他属性。当false
时,应该禁止这些属性。
这是我的 json 模式:
"type": "object",
"properties":
"enabled": "type": "boolean"
,
"required" : ["enabled"],
"additionalProperties" : false,
"if":
"properties":
"enabled": true
,
"then":
"properties":
"description" : "type" : "string" ,
"count": "type": "number"
,
"required" : ["description", "count"]
使用ajv
6.5 版进行验证,无论enabled
的值如何,都需要count
等。例如,对于数据:
"enabled": false
我的验证错误是:
[ keyword: 'required',
dataPath: '',
schemaPath: '#/then/required',
params: missingProperty: 'description' ,
message: 'should have required property \'description\'' ,
keyword: 'required',
dataPath: '',
schemaPath: '#/then/required',
params: missingProperty: 'count' ,
message: 'should have required property \'count\'' ,
keyword: 'if',
dataPath: '',
schemaPath: '#/if',
params: failingKeyword: 'then' ,
message: 'should match "then" schema' ]
如何使用 json-schema draft-7
完成此操作?
请注意,此问题与 jsonSchema attribute conditionally required 类似,但要求更严格。
【问题讨论】:
jsonSchema attribute conditionally required的可能重复 @Jason 不是重复的。大同小异,只是这个问题要求更严格。 我不同意。这是标记为“Enum”的策略的一个非常简单的用例。实际上,您在下面的答案使用了该策略。您的答案应标记为已接受的答案。这比if
-then
-else
的答案好多了。
我同意接受我自己的答案(在 5 小时内),因为这可能是解决我问题的更优雅的方法。我认为这个问题不是重复的,因为它提出了一个不同的(如果相关的话)问题。我不止一次阅读了您对另一个问题的(优秀)答案,但仍然不知道如何解决我/这个特定问题。虽然这里的“枚举”策略变体的适用性对于熟练的从业者 来说可能是显而易见的,但作为新手,我可以说这对我来说并不明显。最好为这个案子写清楚,以可能拯救其他挣扎的人。
【参考方案1】:
为此,您需要在if
语句中使用const
关键字,因此架构将如下所示:
"type": "object",
"properties":
"enabled": "type": "boolean"
,
"required" : ["enabled"],
"additionalProperties" : false,
"if":
"properties":
"enabled": "const": true
,
"then":
"properties":
"description" : "type" : "string" ,
"count": "type": "number"
,
"required" : ["description", "count"]
【讨论】:
【参考方案2】:这受到 vearutop 出色回答的启发。我认为它可能会更短一些,并且可以实现我的既定目的。
"type": "object",
"oneOf" : [
"properties":
"enabled": "const": false
,
"required": ["enabled"],
"additionalProperties": false
,
"properties":
"enabled": "const": true ,
"description": "type": "string" ,
"count": "type": "number"
,
"required": [ "enabled", "description", "count"],
"additionalProperties": false
]
正如 cmets 中所指出的,这是 this answer 中阐明的 Enum 策略的特定变体。
【讨论】:
【参考方案3】:试试这个架构:
"type": "object",
"properties":
"enabled":
"type": "boolean"
,
"required": [
"enabled"
],
"if":
"properties":
"enabled":
"const": true
,
"then":
"properties":
"enabled":
"type": "boolean"
,
"description":
"type": "string"
,
"count":
"type": "number"
,
"additionalProperties": false
,
"required": [
"description",
"count"
]
,
"else":
"properties":
"enabled":
"type": "boolean"
,
"additionalProperties": false
如果您需要"additionalProperties": false
,您必须枚举then
和else
中的所有属性。如果您可以接受其他属性,则架构可能会更简单:
"type": "object",
"properties":
"enabled":
"type": "boolean"
,
"required": [
"enabled"
],
"if":
"properties":
"enabled":
"const": true
,
"then":
"properties":
"description":
"type": "string"
,
"count":
"type": "number"
,
"required": [
"description",
"count"
]
我检查过ajv
cli。
有效:"enabled": false
无效:"enabled": true
有效:"enabled": true, "description":"hi", "count":1
【讨论】:
以上是关于使用 json-schema 来要求或禁止基于另一个属性值的属性?的主要内容,如果未能解决你的问题,请参考以下文章
使用 JSON-Schema 定义模式并使用 Mongoose?
WPF 根据指定条件显示或禁止listView中的每一项的右键菜单