我正在编写一个JSON模式,它能够验证数组中的每个项目都有不同的架构,每个项目的序号索引都是有意义的。,但有些项是可选的。
但是,使用当前的规范(2020-12),我不能对可选项使用prefixItems。要明确:
下面是我试图验证的数据的一个示例:
(没有可选数组元素)
[
{
"name": "Document 1 required",
"url": "random.random/12313213.pdf"
},
{
"name": "Document 2 required",
"url": "random.random/12313213.pdf"
}
](带有可选数组元素)
[
{
"name": "Document 1 required",
"url": "random.random/1231322313.pdf"
},
{
"name": "Optional document 1",
"url": "random.random/1231356213.pdf"
},
{
"name": "Document 2 required",
"url": "random.random/1231893213.pdf"
},
{
"name": "Optional document 2",
"url": "random.random/1231336213.pdf"
}
]下面是我使用的当前模式:
{
"type": "array",
"items": false,
"prefixItems": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Document 1 required"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Document 2 required"
},
"url": {
"type": "string",
"format": "uri"
}
}
}
]
}我尝试过用正确的模式和存根oneOf在可选项位置添加一个{},但它似乎不起作用:
{
"type": "array",
"items": false,
"prefixItems": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Document 1 required"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
{
"oneOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Optional document 1"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
{}
]
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Document 2 required"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
{
"oneOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Optional document 2"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
{}
]
}
]
}还尝试了使用contains和additionalItems的不同方法。但是,它们要么不适用于多个模式,要么不保证可选项的顺序。
注意:该示例使用类似的模式,这些模式可以简化,但用于展示问题所在。
编辑:
正如@Relequestual所指出的,问题在于我试图将元组验证与列表验证相结合,其中数据具有任意长度(必需+可选)和每个项的特定模式。这在当前版本的JSON架构规范中是不可能实现的。
发布于 2022-01-18 19:34:55
您的模式无法工作,因为模式{}始终是真的--因此,当您说"oneOf": [ { .. some schema .. }, {} ]时,本质上是否定第一个模式--因为第二个模式必须始终为真,第一个模式必须为假。这和你想要的正好相反!
我认为你期望prefixItems比实际情况更复杂。prefixItems列表中的每个模式都是可选的,也就是说,如果数据实例中没有相应的项,则不会出现故障。
例如,考虑根据此模式验证此数据[1]:
{
"prefixItems": [
{ "type": "integer" },
false
]
}该评估的总体结果是true --第一个数据元素对"type": integer进行验证,而第二个模式false从不运行,因为没有可以运行的项。如果我们通过了[ 1, 1 ]的数据实例,那么验证就会失败。
如果您想确保所有对应于prefixItems子模式的数据项都实际存在,那么您将需要使用minItems:例如,对于上面的示例,您将添加"minItems": 2。
一个主要的警告是,你需要把你所有需要的东西放在第一位。不能在所需项之间交错可选项,因为prefixItems中的模式总是按顺序应用,而且如果其中一个模式没有计算为真,则不会“跳过”项到下一个模式。第一个prefixItems模式总是应用于第一个数据实例,第二个prefixItems模式总是应用于第二个数据实例,依此类推。
另一方面,如果您可以完全不指定订单,则可以使用多个contains指令(注意,如果没有显式提供,minContains默认为1):
"allOf": [
{ "contains": { schema for one of the required items, that can be anywhere... },
{ "contains": { schema for another required item... },
{ "minContains": 0, "contains": { schema for an optional item... },
...
]还可以使用additionalItems将可选项放入anyOf中(即使可选项的数量非常大或不可预测):
"additionalItems": {
"anyOf": [
{ ..schema of an optional item.. },
{ "" },
...
]
}https://stackoverflow.com/questions/70684901
复制相似问题