8

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.
JamesENL
  • 6,400
  • 6
  • 39
  • 64
Hussain ali
  • 491
  • 3
  • 7
  • 21

2 Answers2

12

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

Ted Epstein
  • 2,639
  • 20
  • 19
4

This is how i implemented the solution.

"anyOf": [{
    "required": ["accountNumber", "parcelNumber", "coordinates"]
}, {
    "required": ["accountNumber", "parcelNumber", "address"]
}]
Hussain ali
  • 491
  • 3
  • 7
  • 21