json - 如何在 JSON 模式中表示多态对象?
问题描述
我正在尝试为 JSON 对象创建一个模式,该对象根据其属性之一的值改变其模式:type
.
像这样:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["INT", "PERCENT"]
}
},
"required": ["type"],
"allOf": [
{
"if": {
"properties": {"type": {"const": "INT"}}
},
"then": {
"properties": {
"value": {"type": "number", "multipleOf": 1}
},
"required": ["value"],
"additionalProperties": false
}
},
{
"if": {
"properties": {"type": {"const": "PERCENT"}}
},
"then": {
"properties": {
"value": {"type": "number"},
"min": {"type": "number"},
"max": {"type": "number"}
},
"required": ["value", "min", "max"],
"additionalProperties": false
}
}
]
}
但是我从我正在尝试的各种验证器那里得到了各种各样的不当行为。
一些有问题的例子在后面提到//
:
{
"type": "PERCENT", // property type has not been defined(?!)
"value": 0.0,
"min": 10,
"max": 25
}
{
"type": "INT", // no errors allowed, and value
"value": 0.1, // should've been flagged as not multiple of 1
"min": 10, // should've been flagged as disallowed additional property
"max": 25 // same as above
}
在此先感谢您的帮助!
解决方案
看来您已经发现问题在于addtionalProperties
只考虑在它定义的子架构中定义的属性。这就是为什么您必须在then
. 您有几个选项可以改进您发布但您不满意的解决方案。
选项1:unevaluatedProperties
2019-09 草案引入了unevaluatedProperties
关键字。如果您在架构的顶层使用它并且不在addtionalProperties
任何地方使用,您将从additionalProperties
. 我看到您使用的是 draft-07,因此您必须升级才能使用此解决方案。
选项 2:布尔模式
您提出的解决方案是在模式中重新定义“类型”属性then
。additionalProperties
只需要声明“类型”,您不需要再次包含它的架构。您可以改用true
或 空模式{}
。
选项 3:propertyNames
而不是additionalProperties
你可以使用propertyNames
. 这允许您声明对象中允许哪些属性名称的列表,而不是按照您想要的方式破解additionalProperties
或true
找出{}
允许的属性名称。
推荐阅读
- swift - 快速核心数据迁移以更改属性类型
- javascript - 从 DOM 同步 JSON
- reactjs - 如何使用 CORS npm 模块
- kotlin - 创建 n 大小零填充 ArrayList 的最佳方法是什么
? - angular - *ngIf 阻止与按钮的交互
- heroku - 使用 Namecheap 和 Heroku 强制 HTTPS
- functional-programming - 示例 F#:求 1000 以下的所有奇数平方之和
- javascript - 防止 div 被其下方的 div 碰撞时向上滚动?
- javascript - JavaScript:隐藏下拉列表中的元素,除了一个
- arrays - 未按数组顺序处理 For 循环