I'm writing a JSON schema capable of validating an array where each item has a different schema and the ordinal index of each item is meaningful but some items are optional.
However, using the current spec (2020-12) I can't use prefixItems with optional items.
To be clear:
- all required items should exist and should be validated against index matching schema
- missing optional items shouldn't invalidate the result
- existing optional items should be validated against the index matching schema
Here is an example of the data I'm trying to validate:
(without optional array elements)
[
{
"name": "Document 1 required",
"url": "random.random/12313213.pdf"
},
{
"name": "Document 2 required",
"url": "random.random/12313213.pdf"
}
]
(with optional array elements)
[
{
"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"
}
]
Here is the current schema I'm using:
{
"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"
}
}
}
]
}
I've tried adding a oneOf in the optional items position with the correct schema and a stub {} but it doesn't seem to work as:
{
"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"
}
}
},
{}
]
}
]
}
Also tried different approaches using contains and additionalItems. However they either don't work for multiple schemas or don't guarantee the order for the optional items.
Note: the example uses similar schemas that could be simplified but it is used to showcase the issue in question.
EDIT:
As pointed out by @Relequestual the issue is that I'm trying to mix tuple validation with list validation where the data has an arbitrary length (required + optional) with a specific schema for each item. This is not possible to achieve with the current version of the JSON Schema specification.