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

56 Views Asked by At

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
        }
    }
}
1

There are 1 best solutions below

3
jareon On BEST ANSWER

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
        }
      ]
    }
  }
}