Json Schema:仅当深层嵌套对象中存在特定属性时才需要属性 [英] Json Schema: Require a property only when a specific property is present in a deep nested object

查看:177
本文介绍了Json Schema:仅当深层嵌套对象中存在特定属性时才需要属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to build a json schema (draft 4) that requires a property based on the presence of a property in another nested object. I already searched and tried a lot of things (anyOf, oneOf, not, dependencies) with no luck.

也许在json模式中这不可能吗?

Maybe this is not possible to in json 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",
          "properties": {
            "total": { "type": "string" }
          }
        }
      }
    }
  }
}

这是bananas.json

And this is 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" }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

当数组中的一个或多个对象具有事物"属性时(在香蕉->香蕉->事物上),我需要这样做. 然后,应该需要(dog-> something)处的属性"thing".

I need that when one or more objects in the array have a 'thing' property (at bananas -> banana -> thing). Then the property 'thing' at (dog -> thing) should be required.

任何帮助将不胜感激.

推荐答案

您需要两件事来表达您的约束.第一个是包含",另一个是蕴涵".我已经在definitions部分组织了每个活动.

You need two things to express your constraint. The first is "contains" and the other is "implication". I've organized each in the definitions section.

包含

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

The items keyword allows us to require that all items in an array are valid against a schema. If it is not true that all of the items in the array are not valid against the schema, then we know that at least one item is valid.

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

如果您能够升级到JSON Schema draft-06,则添加contains关键字可以使此操作变得更加容易.

If you are able to upgrade to JSON Schema draft-06, a contains keyword was added to make this much easier.

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

含义

通过蕴含,您可以执行条件操作.如果条件为真或约束为真(或两者都为真),则条件模式暗含约束模式.这实际上与说相同,如果条件为真,那么约束也必须为真.

Implication allows you to do something like a conditional. The condition schema implies the constraint schema if either the condition is true, or the constraint is true (or both are true). It's effectively the same as saying, if the condition is true then the constraint must also be true.

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

JSON Schema draft-07添加了if-then-else关键字,试图更好地解决这种情况.我个人不喜欢这样做的方式,以至于我会坚持这种暗示模式,但是在这种情况下,是万一您想尝试一下.

JSON Schema draft-07 adds the if-then-else keywords in attempt to address this case better. I personally dislike the way this was done enough that I'll stick with the implication pattern for this kind of thing, but here it is in case you want to try it.

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

这篇关于Json Schema:仅当深层嵌套对象中存在特定属性时才需要属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆