Hussain ali
Hussain ali

Reputation: 512

Json Schema - How to make anyOf two or more properties required

I have this parent schema:

{
    "definitions": {
        "parcel": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "string"
                },
                "accountNumber": {
                    "type": "string"
                },
                "parcelNumber": {
                    "type": "string"
                },
                "propertyType": {
                    "type": "string"
                },
                "address": {
                    "$ref": "address.json#/definitions/address"
                },
                "coordinates": {
                    "$ref": "coordinates.json#/definitions/coordinates"
                }
            },
            "required": ["accountNumber", "parcelNumber"]
        }
    }
}

Following are the referenced sub-schemas:

{
    "definitions": {
        "address": {
            "type": "object",
            "properties": {
                "addressString": {
                    "type": "string",
                    "addressType": {
                        "enum": ["residential", "business"]
                    }
                },
                "required": ["addressString"]
            }
        }
    }
}

    {
    "definitions": {
        "coordinates": {
            "type": "object",
            "properties": {
                "latitude": {
                    "type": "number"
                },
                "longitude": {
                    "type": "number"
                },
                "projection": {
                    "type": "string"
                }
            },
            "required": ["latitude ", "longitude", " projection"]
        }
    }
}

I want to apply the following conditions to the parent schema.

  1. Either address or coordinates or both are provided.
  2. It should fail the validation if neither address nor coordinates is provided.

Upvotes: 10

Views: 17097

Answers (2)

Ted Epstein
Ted Epstein

Reputation: 2869

Your anyOf solution works. You can make it a little cleaner by separating the fixed required properties (accountNumber and parcelNumber) from the anyOf property group:

{
  "type": "object",
  "required": [
    "accountNumber",
    "parcelNumber"
  ],
  "anyOf": [
    {"required" : ["address"]},
    {"required" : ["coordinates"]}
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "accountNumber": {
      "type": "string"
    },
    "parcelNumber": {
      "type": "string"
    },
    "propertyType": {
      "type": "string"
    },
    "address": {
      "type": "object",
      "properties": {
        "addressString": {
          "type": "string"
        },
        "addressType": {
          "enum": [
            "residential",
            "business"
          ]
        }
      },
      "required": [
        "addressString"
      ]
    },
    "coordinates": {
      "type": "object",
      "properties": {
        "latitude": {
          "type": "number"
        },
        "longitude": {
          "type": "number"
        },
        "projection": {
          "type": "string"
        }
      },
      "required": [
        "latitude",
        "longitude",
        "projection"
      ]
    }
  }
}

Here's a gist for reference:

http://jsonschemalint.com/#/version/draft-05/markup/json?gist=f36d9a7e080c4d25dbbf09b7dd03137e

Upvotes: 14

Hussain ali
Hussain ali

Reputation: 512

This is how i implemented the solution.

"anyOf": [{
    "required": ["accountNumber", "parcelNumber", "coordinates"]
}, {
    "required": ["accountNumber", "parcelNumber", "address"]
}]

Upvotes: 4

Related Questions