【问题标题】:Json Schema: Require a property only when a specific property is present in a deep nested objectJson Schema:仅当深层嵌套对象中存在特定属性时才需要属性
【发布时间】:2018-06-09 11:51:40
【问题描述】:

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

也许这在 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" }
          }
        }
      }
    }
  }
}

这是香蕉.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 -> thing) 处的属性 'thing'。

任何帮助将不胜感激。

【问题讨论】:

    标签: jsonschema


    【解决方案1】:

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

    包含

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

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

    如果您能够升级到 JSON Schema Draft-06,则添加了一个 contains 关键字来简化此操作。

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

    含义

    蕴含允许你做一些类似条件的事情。如果条件为真或约束为真(或两者都为真),则条件模式暗示约束模式。这实际上等同于说,如果条件为真,则约束也必须为真。

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

    【讨论】:

    • 嗨,杰森,非常感谢您的详尽解释。它帮助我真正理解了如何用 json-schema 做复杂的逻辑。谢谢!
    • 由于明确的示例如何将布尔表达式转换为 JSON 模式语法,因此肯定会投赞成票。
    猜你喜欢
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 2019-04-04
    • 2021-01-21
    • 1970-01-01
    相关资源
    最近更新 更多