我有一个json文档,我正在尝试使用以下表单进行验证:
...
"products": [{
"prop1": "foo",
"prop2": "bar"
}, {
"prop3": "hello",
"prop4": "world"
},
...
一个物体可能有多种不同的形式。我的模式如下:
...
"definitions": {
"products": {
"type": "array",
"items": { "$ref": "#/definitions/Product" },
"Product": {
"type": "object",
"oneOf": [
{ "$ref": "#/definitions/Product_Type1" },
{ "$ref": "#/definitions/Product_Type2" },
...
]
},
"Product_Type1": {
"type": "object",
"properties": {
"prop1": { "type": "string" },
"prop2": { "type": "string" }
},
"Product_Type2": {
"type": "object",
"properties": {
"prop3": { "type": "string" },
"prop4": { "type": "string" }
}
...
除此之外,可以通过进一步使用anyOf
或oneOf
来间接地影响各个产品阵列对象的某些属性。
我在使用内置模式验证的VSCode中遇到了问题,它会为products
数组中与Product_Type1
不匹配的每个项抛出错误。
因此,验证器似乎锁定了它找到的第一个oneOf
,不会针对任何其他类型进行验证。
我在jsonschema.org上没有发现oneOf
机制的任何限制。这里也没有提到它在专门处理数组的页面中使用:https://json-schema.org/understanding-json-schema/reference/array.html
我尝试的是可能的吗
您的通用方法很好。让我们举一个稍微简单一点的例子来说明出了什么问题。
给定此模式
{
"oneOf": [
{ "properties": { "foo": { "type": "integer" } } },
{ "properties": { "bar": { "type": "integer" } } }
]
}
这个例子
{ "foo": 42 }
乍一看,它与/oneOf/0
匹配,而与oneOf/1
不匹配。它实际上匹配两个模式,这违反了oneOf
和oneOf
所施加的唯一约束。
请记住,JSON模式中的每个关键字都是一个约束。任何未被架构明确排除的内容都是允许的。/oneOf/1
模式中没有任何内容表明不允许使用"foo"属性。也没有说"foo"是必需的。它只是说,如果实例有一个关键字"foo",那么它必须是一个整数。
要解决此问题,您需要required
,也可能需要additionalProperties
,具体取决于情况。我在这里展示了如何使用additionalProperties
,但我建议您不要使用它,除非您需要,因为它确实有一些有问题的属性。
{
"oneOf": [
{
"properties": { "foo": { "type": "integer" } },
"required": ["foo"],
"additionalProperties": false
},
{
"properties": { "bar": { "type": "integer" } },
"required": ["bar"],
"additionalProperties": false
}
]
}