JsonSchema:根据另一个属性

时间:2018-04-11 21:31:37

标签: 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
}

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

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

value

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

3 个答案:

答案 0 :(得分:7)

解决这些问题的最佳方法是使用定义将复杂验证与其余模式分开,并将其包含在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" }
      }
    }
  }
}

答案 1 :(得分:2)

如果您能够使用JSON Schema的最新draft-7版本,则可以if then else使用oneOf

虽然使用{ "type": "object", "properties": { "foo": { "type": "string" }, "bar": { "type": "string" } }, "if": { "properties": { "foo": { "enum": ["bar"] } } }, "then": { "required": ["bar"] } } 也是一种有效的方法,但是其他人可能不会在以后检查您的架构时这样做。

我已将答案中的示例复制到https://tools.ietf.org/html/draft-handrews-json-schema-validation-00#section-6.6

  

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

select 
    c.CompanyName 
from Customers as c 
inner join Orders as O on > o.OrderID=c.CustomerID 
inner join [Order Details] as OD on > od.ProductID=o.OrderID 
inner join Products as p on > p.ProductID=od.ProductID 
where p.UnitPrice < 5

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

答案 2 :(得分:0)

可能有一种更简洁的方法来做到这一点,但这将有效:

{
  "$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
}