当元素是可选的时,如何在json模式中定义choice元素?

jav*_*dev 8 json jsonschema

------------ Josn schema -----------

{
    "type": "object",
    "properties": {
        "street_address": {
            "type": "string"
        },
        "city": {
            "type": "string"
        },
        "state": {
            "type": "string"
        }
    },
    "required": [
        "street_address"
    ],
    "additionalProperties": false
}
Run Code Online (Sandbox Code Playgroud)

在上面的模式中,我想在城市和州之间创建一个选择.无论是城市还是州都可以来json.所以json下面会无效

{
    "street_address": "abc",
    "city": "anv",
    "state": "opi"
}
Run Code Online (Sandbox Code Playgroud)

以下一个应该是有效的

{
    "street_address": "abc"
}
Run Code Online (Sandbox Code Playgroud)

要么

{
    "street_address": "abc",
    "city": "anv"
}
Run Code Online (Sandbox Code Playgroud)

要么

{
    "street_address": "abc",
    "state": "opi"
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮我修改上面的架构来完成目标.

jru*_*ren 5

当只有一个替代品应该持有时使用"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
}
Run Code Online (Sandbox Code Playgroud)

  • 这个模式违反了`{ "street_address": "abc" }` 应该是有效的要求。 (2认同)

Bil*_*our 1

您需要使用“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"
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

你会注意到,它有点重复。由于在您的示例中,您仅为每个属性提供了一个“类型”,因此重复性还不错。但是,如果您有更复杂的属性,您可以考虑deifinitions在顶部使用每个属性仅定义一次,然后使用$ref引用该定义。这是一篇关于这一点的好文章