简体   繁体   中英

Validate JSON Schema based on “type” property

I have the following JSON which validates against my current schema:

    {
      "information": [
        {
          "value": "closed",
          "type": "power"
        },
        {
          "value": "on",
          "type": "door"
        }
      ]
    }

However, I want this validation to fail (since open / closed should relate to door , and on / off should only relate to power .

How can I tie the two together?

My current working schema:

  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "Type": {
      "type": "string",
      "enum": ["power", "door"]
    },
    "Power": {
      "type": "string",
      "enum": ["on", "off"]
    },
    "Door": {
      "type": "string",
      "enum": ["open", "closed"]
    },
    "InformationField": {
      "type": "object",
      "required": [ "type", "value" ],
      "properties": {
        "label": { "type": "string" },
        "value": {
          "anyOf": [
            { "$ref": "#/definitions/Power"},
            { "$ref": "#/definitions/Door"}
          ]
        },
        "type": { "$ref": "#/definitions/Type" }
      }
    },
    "Information": {
      "type": "array",
      "items": { "$ref": "#/definitions/InformationField" }
    },
  },
  "properties": {
    "information": { "$ref": "#/definitions/Information" }
  },
}

I have a lot of types, so I want to do this in the cleanest way possible.

Here is one of my attempts, which fails to validate correctly:

{ 
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "Type": {
      "type": "string",
      "enum": ["power", "door"]
    },
    "Power": {
      "type": "string",
      "enum": ["on", "off"]
    },
    "Door": {
      "type": "string",
      "enum": ["open", "closed"]
    },
    "InformationField": {
      "type": "object",
      "required": [ "label", "value" ],
      "properties": {
        "label": { "type": "string" },
        "type": { "$ref": "#/definitions/Type" }
      },
      "anyOf": [
        {
          "if": {
           "properties": { "type": { "const": "power" } }
          },
          "then": {
            "properties": { "value": { "$ref": "#/definitions/Power" } }
          }
        },
        {
          "if": {
            "properties": { "type": { "const": "door" } }
          },
          "then": {
            "properties": { "value": { "$ref": "#/definitions/Door" } }
          }
        }
      ]
    },
    "Information": {
      "type": "array",
      "items": { "$ref": "#/definitions/InformationField" }
    },
  },
  "properties": {
    "information": { "$ref": "#/definitions/Information" }
  },
}

(Validates, even though it shouldn't ...)

Changed anyOf to allOf in my attempt, which fixes validation.

My reasoning as to why this works:

From the anyOf JSON schema spec:

5.5.4.2. Conditions for successful validation

An instance validates successfully against this keyword if it validates successfully against at least one schema defined by this keyword's value.

If my first if condition is false, then it doesn't evaluate the then , and is therefore valid .

Using allOf evaluates every condition's validation (not the condition itself).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM