如何在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:Boolean模式

你想出的解决方案是重新定义"类型"。属性在then模式中。additionalProperties只需要"type"要声明,您不需要再次包含它的模式。您可以使用true或空模式{}

选项3:propertyNames

可以用propertyNames代替additionalProperties。这允许您声明对象中允许的属性名列表,而不是用true{}破解additionalProperties,以确定允许的属性名。

我找到了一种方法来得到我想要的,但这并不意味着我喜欢它。必须重新定义"类型"我觉得不太对。

{
"$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},
"type": {"type": "string"}
},
"required": ["value", "type"],
"additionalProperties": false
}
},
{
"if": {
"properties": {"type": {"const": "PERCENT"}}
},
"then": {
"properties": {
"value": {"type": "number"},
"min": {"type": "number"},
"max": {"type": "number"},
"type": {"type": "string"}
},
"required": ["value", "min", "max", "type"],
"additionalProperties": false
}
}
]
}

测试……

这验证:

{
"type": "PERCENT", 
"value": 0,
"min": 10,
"max": 20
}

{
"type": "INT", 
"value": 0
}

这个错误在我想要的方式:

{
"type": "INT", 
"value": 0.1,  // not a multiple of 1
"min": 4, //  not expected
"max": 5 // not expected
}

{
"type": "PERCENT", 
"value": 0.1,
"max": 5   // min is a required property
}

相关内容

  • 没有找到相关文章

最新更新