JsonSchema: Validate type based on value of another property

前端 未结 3 511
小蘑菇
小蘑菇 2021-01-12 14:43

I am using the following schema to validate my json:

{
    \"$schema\": \"http://json-schema.org/schema#\",
    \"title\": \" Rules\",
    \"description\": \         


        
相关标签:
3条回答
  • 2021-01-12 14:53

    If you are able to use the latest draft-7 version of JSON Schema, you can use if then else, as per https://tools.ietf.org/html/draft-handrews-json-schema-validation-00#section-6.6

    Although, using oneOf is also a valid approach, it might not be as clear to someone else inspecting your schema at a later date.

    I've copied an example from an answer to another question:

    If the "foo" property equals "bar", Then the "bar" property is required

    {
      "type": "object",
      "properties": {
        "foo": { "type": "string" },
        "bar": { "type": "string" }
      },
      "if": {
        "properties": {
          "foo": { "enum": ["bar"] }
        }
      },
      "then": { "required": ["bar"] }
    }
    

    (You may want to check the draft support of the library you are using.)

    0 讨论(0)
  • 2021-01-12 15:05

    The best way to solve these kinds of problems is to separate the complex validation from the rest of the schema using definitions and include it with an allOf. In this solution, I use implication to enforce the validation.

    {
      "type": "object",
      "properties": {
        "rules": {
          "type": "array",
          "items": { "$ref": "#/definitions/rule" }
        }
      },
      "required": ["rules"],
      "definitions": {
        "rule": {
          "type": "object",
          "properties": {
            "precedence": { "type": "number", "minimum": 0 },
            "conditions": {
              "type": "array",
              "items": { "$ref": "#/definitions/condition" }
            }
          },
          "required": ["precedence", "conditions"]
        },
        "condition": {
          "type": "object",
          "properties": {
            "field": { "enum": ["Name", "Size"] },
            "relation": { "enum": ["is", "is not", "is not one of", "is one of"] },
            "value": { "type": ["array", "string", "number"] }
          },
          "required": ["field", "relation", "value"],
          "allOf": [{ "$ref": "#/definitions/array-condition-implies-value-is-array" }]
        },
        "array-condition-implies-value-is-array": {
          "anyOf": [
            { "not": { "$ref": "#/definitions/is-array-condition" } },
            { "$ref": "#/definitions/value-is-array" }
          ]
        }
        "is-array-condition": {
          "properties": {
            "relation": { "enum": ["is not one of", "is one of"] }
          },
          "required": ["relation"]
        },
        "value-is-array": {
          "properties": {
            "value": { "type": "array" }
          }
        }
      }
    }
    
    0 讨论(0)
  • 2021-01-12 15:14

    There may be a more concise way to do this, but this will work:

    {
      "$schema": "http://json-schema.org/schema#",
      "title": "Rules",
      "description": "Describes a set of rules",
      "definitions": {
        "field": {
          "type": "string",
          "enum": ["Name", "Size"]
        }
      },
      "type": "object",
      "properties": {
        "rules": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "precedence": {
                "type": "number",
                "minimum": 0
              },
              "conditions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "oneOf": [
                    {
                      "properties": {
                        "field": {
                          "$ref": "#/definitions/field"
                        },
                        "relation": {
                          "type": "string",
                          "enum": ["is", "is not"]
                        },
                        "value": {
                          "type": ["string", "number"]
                        }
                      },
                      "required": ["field", "relation", "value"],
                      "additionalProperties": false
                    },
                    {
                      "properties": {
                        "field": {
                          "$ref": "#/definitions/field"
                        },
                        "relation": {
                          "type": "string",
                          "enum": ["is not one of", "is one of"]
                        },
                        "value": {
                          "type": ["array"]
                        }
                      },
                      "required": ["field", "relation", "value"],
                      "additionalProperties": false
                    }
                  ]
                }
              }
            },
            "required": ["precedence", "conditions"],
            "additionalProperties": false
          }
        }
      },
      "required": ["rules"],
      "additionalProperties": false
    }
    
    0 讨论(0)
提交回复
热议问题