Json Schema:仅当深层嵌套对象中存在特定属性时才需要属性

时间:2017-12-28 23:54:33

标签: jsonschema

我需要构建一个json模式(草案4),它需要一个基于另一个嵌套对象中属性的属性的属性。我已经搜索并尝试了很多东西(anyOf,oneOf,not,依赖)没有运气。

也许这在json架构中是不可能的?

这是我的简化架构:

{
  "$schema": "http://json-schema.org/draft-04/schema#",  
  "type": "object",
  "required": ["dog"],
  "properties": {
    "dog": {
      "type": "object",
      "required": ["bananas"],
      "properties": {
        "bananas": { "$ref": "bananas.json" },
        "thing": {
          "type": "object",
          "properties": {
            "total": { "type": "string" }
          }
        }
      }
    }
  }
}

这是bananas.json

{
  "$schema": "http://json-schema.org/draft-04/schema#",  
  "type": "object",
  "required": ["banana"],
  "definitions": {
    "non-empty-string": {
        "type": "string",
        "minLength": 1
    }
  },
  "properties": {
    "banana": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["unit"],
        "properties": {
          "unit": { "type": "string" },
          "thing": {
            "type": "object",
            "anyOf": [
              { "required": [ "tax_transfers" ] },
              { "required": [ "tax_retentions" ] }
            ],
            "properties": {
              "tax_transfers": {
                "type": "object",
                "required": ["tax_transfer"],
                "properties": {
                  "tax_transfer": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "properties": {
                        "rate": { "type": "string" }
                      }
                    }
                  }
                }
              },
              "tax_retentions": {
                "type": "object",
                "required": ["tax_retention"],
                "properties": {
                  "tax_retention": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                      "type": "object",
                      "properties": {
                        "rate": { "type": "string" }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

当数组中的一个或多个对象具有'thing'属性(在香蕉 - > banana - >事物)时,我需要这样做。

然后应该要求(狗 - >事物)的属性'东西'

任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:2)

你需要两件事来表达你的约束。第一个是“包含”,另一个是“含义”。我已在definitions部分组织了每个部分。

<强>包含

items关键字允许我们要求数组中的所有项对模式都有效。如果数组中的所有项都不对模式有效,那么我们知道至少有一个项是有效的。

{
  "not": {
    "items": { "not": { ... schema ... } }
  }
}

如果您能够升级到JSON Schema draft-06,则会添加contains关键字,以便更轻松。

{
  "contains": { ... schema ... }
}

<强>蕴涵

Implication允许您执行类似条件的操作。如果条件为真,或者约束为真(或两者都为真),则条件模式意味着约束模式。它实际上与说法相同,如果条件为真,则约束也必须为真。

{
  "anyOf": [
    { "not": { ... condition schema ... } },
    { ... constraint schema ... }
  ]
}

JSON Schema draft-07添加了if - then - else个关键字,以便更好地解决此问题。我个人不喜欢这样做的方式,我会坚持使用这种事情的蕴涵模式,但这是为了以防你想尝试。

{
  "if": { ... schema ... },
  "then": { ... schema ... },
  "else": { ... schema ... }
}

一起

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": ["dog"],
  "properties": {
    "dog": {
      "type": "object",
      "required": ["bananas"],
      "properties": {
        "bananas": { "$ref": "bananas.json" },
        "thing": { "type": "object" }
      }
    }
  },
  "allOf": [
    { "$ref": "#/definitions/banana-things-implies-dog-things" }
  ],
  "definitions": {
    "banana-has-things": {
      "properties": {
        "dog": {
          "properties": {
            "bananas": {
              "properties": {
                "banana": {
                  "not": {
                    "items": { "not": { "required": ["things"] } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "banana-things-implies-dog-things": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/banana-has-things" }},
        {
          "properties": {
            "dog": { "required": ["things"] }
          }
        }
      ]
    }
  }
}