JsonSchema:根据另一个属性的值验证类型

Joe*_*ris 4 json jsonschema

我使用以下架构来验证我的json:

{
    "$schema": "http://json-schema.org/schema#",
    "title": " Rules",
    "description": "Describes a set of rules",
    "type": "object",
    "properties": {
        "rules": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "precedence": {
                        "type": "number",
                        "minimum": 0
                    },
                    "conditions": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "field": {
                                    "type": "string",
                                    "enum": [ "Name", "Size" ]
                                },
                                "relation": {
                                    "type": "string",
                                    "enum": [ "is", "is not", "is not one of", "is one of" ]
                                },
                                "value": {
                                    "type": ["array", "string", "number"]
                                }
                            },
                            "required": ["field", "relation", "value"],
                            "additionalProperties": false
                        }
                    }                       
                },
                "required": ["precedence", "conditions"],
                "additionalProperties": false
            }
        }
    },
    "required": ["rules"],
    "additionalProperties": false
}
Run Code Online (Sandbox Code Playgroud)

我想设置一个依赖项来验证当relation属性的值具有值is one of或值时is not one of,value属性的类型只能是array

例如,以下json不应该验证,因为它使用关系值is not one of并且value属性不是数组:

{
    "rules": [{
            "precedence": 0,
            "conditions": [{
                    "field": "Name",
                    "relation": "is not one of",
                    "value": "Mary"
                }
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

是否可以设置依赖关系来验证这种方式?

Jas*_*ers 8

解决这些问题的最佳方法是使用定义将复杂验证与其余模式分开,并将其包含在内allOf.在此解决方案中,我使用暗示来强制执行验证.

{
  "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" }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Rel*_*ual 6

如果您能够使用最新的 JSON Schema 草案 7 版本,则可以使用if then else,根据https://tools.ietf.org/html/draft-handrews-json-schema-validation-00#section-6.6

尽管 usingoneOf也是一种有效的方法,但对于以后检查您的架构的其他人来说可能并不那么清楚。

我从另一个问题的答案中复制了一个示例:

如果“foo”属性等于“bar”,则需要“bar”属性

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "if": {
    "properties": {
      "foo": { "enum": ["bar"] }
    }
  },
  "then": { "required": ["bar"] }
}
Run Code Online (Sandbox Code Playgroud)

(您可能需要检查您正在使用的库的支持草案。)