【问题标题】:How to define choice element in json schema when elements are optional?当元素是可选的时,如何在 json 模式中定义选择元素?
【发布时间】:2014-11-20 19:50:37
【问题描述】:

------------Josn 模式------------

{
    "type": "object",
    "properties": {
        "street_address": {
            "type": "string"
        },
        "city": {
            "type": "string"
        },
        "state": {
            "type": "string"
        }
    },
    "required": [
        "street_address"
    ],
    "additionalProperties": false
}

在上面的架构中,我想在城市和州之间创建一个选择。也就是说,城市或州都可以以 json 形式出现。所以下面的json会是无效的

{
    "street_address": "abc",
    "city": "anv",
    "state": "opi"
}

低于1的应该是有效的

{
    "street_address": "abc"
}

{
    "street_address": "abc",
    "city": "anv"
}

{
    "street_address": "abc",
    "state": "opi"
}

有人可以帮我修改上述架构以实现目标吗?

【问题讨论】:

    标签: json jsonschema


    【解决方案1】:

    当只有一个选项应该成立时使用“oneOf”,当至少一个选项应该成立时使用“anyOf”。

    您无需在 oneOf 中重复常用属性。实现目标的最短途径是:

    {
        "type" : "object",
        "properties" : {
            "street_address" : {
                "type" : "string"
            },
            "city" : {
                "type" : "string"
            },
            "state" : {
                "type" : "string"
            }
        },
        "oneOf" : [{
                "required" : ["city"]
            }, {
                "required" : ["state"]
            }
        ],
        "required" : [
            "street_address"
        ],
        "additionalProperties" : false
    }
    

    【讨论】:

    • 此架构违反了{ "street_address": "abc" } 应该有效的要求。
    【解决方案2】:

    这是一个满足所有四个条件的架构:

        {
            "type": "object",
            "properties": {
                "street_address": {
                    "type": "string"
                },
                "city": {
                    "type": "string"
                },
                "state": {
                    "type": "string"
                }
            },
            "required": [
                "street_address"
            ],
            "anyOf": [{}, {
                "required": ["city"]
            }, {
                "required": ["state"]
            }],
            "not": {
                "required": ["city", "state"]
            },
            "additionalProperties": false
        }
    

    【讨论】:

      【解决方案3】:

      我发现enum 属性对这个用例很有用。

      例子:

      schema = {
          "type": "array", 
          "items": {
              "enum": ["choice1", "choice2"]
          }
      }
      
      validate(
          instance=["choice1"], 
          schema=schema
      )
      # all good
      
      validate(
          instance=["something-else"], 
          schema=schema
      )
      # ValidationError
      

      参考: https://json-schema.org/understanding-json-schema/reference/combining.html#combining-schemas

      希望对你有帮助。

      【讨论】:

        【解决方案4】:

        您需要使用“oneOf”。像这样:

        {
            "type": "object",
            "oneOf": [
                {
                    "properties": {
                        "street_address": {
                            "type": "string"
                        },
                        "city": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "street_address"
                    ]
                },
                {
                    "properties": {
                        "street_address": {
                            "type": "string"
                        },
                        "state": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "street_address"
                    ]
                }
            ]
        }
        

        您会注意到,它有点重复。由于在您的示例中,您只为每个属性提供了一个“类型”,因此重复并不是那么糟糕。但是如果您有更复杂的属性,您可以考虑使用deifinitions 将每个属性仅定义一次,在顶部,然后使用$ref 来引用定义。 Here's a good article on that.

        【讨论】:

        • 此架构违反了{ "street_address": "abc" } 应该有效的要求,因为两个 oneOf 分支都匹配。
        猜你喜欢
        • 2010-09-11
        • 2011-07-04
        • 1970-01-01
        • 1970-01-01
        • 2013-01-06
        • 1970-01-01
        • 2019-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多