tscherg
tscherg

Reputation: 1082

JSON Schema to validate interdependent array structure

I am trying to write a schema validating arrays with the following structural constraints:

so the valid arrays are

[1],
[2],
[3],
[4],
[5],
[2,5],
[3,5],
[4,5]

I started writing a schema as follows:

{
    "type": "array",
    "oneOf": [
        { "items": { "enum": [1] } },
        {
            "anyOf": [
                ???
            ]
        }
    ]
}

I can't get the ??? part to work. Is it possible at all? NOTE: I would like to avoid hardcoding all possible arrays, as I have to validate more complex structures - this is only an example. Also, the optimum is a solution using only anyOf, allOf, oneOf, not, avoiding keywords like minItems

Upvotes: 1

Views: 261

Answers (1)

Jason Desrosiers
Jason Desrosiers

Reputation: 24409

This passes all of your constraints.

{
  "type": "array",
  "anyOf": [
    { "enum": [[1]] },
    {
      "items": { "enum": [2, 3, 4, 5] },
      "oneOf": [
        { "$ref": "#/definitions/doesnt-contain-2-3-or-4" },
        { "$ref": "#/definitions/contains-2" },
        { "$ref": "#/definitions/contains-3" },
        { "$ref": "#/definitions/contains-4" }
      ]
    }
  ],
  "definitions": {
    "doesnt-contain-2-3-or-4": {
      "items": { "not": { "enum": [2, 3, 4] } }
    },
    "contains-2": {
      "not": {
        "items": { "not": { "enum": [2] } }
      }
    },
    "contains-3": {
      "not": {
        "items": { "not": { "enum": [3] } }
      }
    },
    "contains-4": {
      "not": {
        "items": { "not": { "enum": [4] } }
      }
    }
  }
}

If you have the option of using the new draft-06 keywords contains and const, it's actually a pretty clean solution. There is a little duplication, but I don't think that can be helped.

{
  "type": "array",
  "anyOf": [
    { "const": [1] },
    {
      "items": { "enum": [2, 3, 4, 5] },
      "oneOf": [
        { "not": { "contains": { "enum": [2 ,3, 4] } } },
        { "contains": { "const": 2 } },
        { "contains": { "const": 3 } },
        { "contains": { "const": 4 } }
      ]
    }
  ]
}

Upvotes: 1

Related Questions