0

What is the right way to require an array element with particular field if other array element is presented?
E.g. forcing bread in case if butter is here:

+-------+-------+--------+
| valid | bread | butter |
+-------+-------+--------+
|   +   |   -   |   -    |
|   +   |   +   |   -    |
|   +   |   +   |   +    |
|   -   |   -   |   +    |
+-------+-------+--------+

Products example:

{
  "products": [
    {
      "name": "butter"
    },
    {
      "name": "bread"
    }
  ]
}

Based on post and Combining schemas, it is possible to check that there is NO butter, otherwise array has bread:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Complex Array",

  "anyOf": [
    { "not": { "$ref": "#/definitions/contains-name-butter" } },
    { "$ref": "#/definitions/contains-name-bread" }
  ],
  "definitions": {
    "contains-name-butter": {
      "type": "object",
      "properties": {
        "products": {
          "type": "array",
          "contains": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "pattern": "^butter$"
              }
            }
          }
        }
      }
    },
    "contains-name-bread": {
      "type": "object",
      "properties": {
        "products": {
          "type": "array",
          "contains": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "pattern": "^bread$"
              }
            }
          }
        }
      }
    }
  }
}

Now if bread got removed - schema validation will break.

If there any way to make it simpler? Especially if in future adding more dependency is planned.

Ilya Lepesh
  • 103
  • 2

1 Answers1

2

In logical terms, what you seem to want is: if the array contains an item with property "name" whose value is "butter", then require an item with property "name" and value "bread":

  "type" : "array",
  "if" : {
    "contains" : {
      "type: "object",
      "properties" : {
        "name" : {
          "const" : "butter"
        }
      }
    }
  },
  "then" : {
    "contains" : {
      "required": [ "name" ],
      "properties" : {
        "name" : {
          "const" : "bread"
        }
      }
    }
  }
}

(I also, simplified "pattern": "^bread$" as "const":"bread".)

Ether
  • 53,118
  • 13
  • 86
  • 159