jsonjsonschemajson-schema-validator

JSON schema to check if only one of the array items contains a property


Is there a way to check whether a property is present in the array, but only in one of the items?

In the following example, the "filename" and "format" must be present at least in one and only in one array item.

Valid JSON examples:

{
    "myarray": [
        {
            "name": "Example 1"
        },
        {
            "filename": "example.txt",
            "format": "txt"
        }
    ]
}
{
    "myarray": [
        {
            "name": "Example 2"
            "filename": "example.txt"
        },
        {
            "format": "txt"
        }
    ]
}

Invalid JSON example:

{
    "myarray": [
        {
            "name": "Example 3"
            "filename": "example.txt"
            "format": "txt"
        },
        {
            "filename": "example3.txt"
        }
    ]
}

I was able to reach this by the following schema, but it works for one property only. When I add format, it does not work either for "filename" or for "format".

"myarray": {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "filename": {
                "type": "string"
            }
        }
    },
    "additionalProperties": false,
    "contains": {
        "required": [
            "filename"
        ]
    },
    "not": {
        "items": {
            "required": [
                "filename"
            ],
            "minProperties": 1
        }
    }
}

Solution

  • You can use allOf since you need to match multiple and minContains and maxContains since you have a at least one and only one condition.

    {
      "properties": {
        "myarray": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "filename": {
                "type": "string"
              },
              "format": {
                "type": "string"
              }
            }
          },
          "allOf": [
            {
              "contains": {
                "required": [
                  "filename"
                ]
              },
              "minContains": 1,
              "maxContains": 1
            },
            {
              "contains": {
                "required": [
                  "format"
                ]
              },
              "minContains": 1,
              "maxContains": 1
            }
          ]
        }
      }
    }