如何确保 "oneOf" 子句中的模式最多匹配一次?

How to ensure a schema inside of a "oneOf" clause is matched at most once?

给出这样的架构:

{
  "type": "array",
  "items": {
    "oneOf": [
      {"$ref": "#/definitions/foo"},
      {"$ref": "#/definitions/bar"},
      {"$ref": "#/definitions/baz"},
    ]
  },
  "definitions": {...}
}

例如,我如何确保数组中至多有一项与模式 "foo" 匹配?

您不能按照您的要求对数组项应用一般基数约束。 但根据您的业务需求,您可以使用以下三种备选方案:

首先,如果foo最多只能出现一次,你可以考虑把它从数组中取出来,作为一个可选的属性。

{
"type":"object",
"properties":{
"foo":{
            "$ref" : "#/definitions/foo"
        }
        "otherItems" : {
            "type" : "array",
            "items" : {
                "oneOf" : [{
                        "$ref" : "#/definitions/bar"
                    }, {
                        "$ref" : "#/definitions/baz"
                    }
                ]
            },
            "definitions" : {}
        }
    }
}

其次,如果不需要特定的顺序,您也可以使用对象而不是数组来实现类似的结构约束:

{
    "type" : "object",
    "properties" : {
        "foo" : {
            "$ref" : "#/definitions/foo"
        }
    },
    "additionalItems" : {
        "oneOf" : [{
                "$ref" : "#/definitions/bar"
            }, {
                "$ref" : "#/definitions/baz"
            }
        ]
    }
}

最后但同样重要的是,如果您可以强制您的客户在 foo 对象出现时将其发送到数组的第一位,那么以下架构将最接近您的架构:

{
    "type" : "array",
    "items" : [{
            "oneOf" : [{
                    "$ref" : "#/definitions/foo"
                }, {
                    "$ref" : "#/definitions/bar"
                }, {
                    "$ref" : "#/definitions/baz"
                },
            ]
        }

    ],
    "additionalItems" : {
        "oneOf" : [{
                "$ref" : "#/definitions/bar"
            }, {
                "$ref" : "#/definitions/baz"
            }
        ]
    }

}