首页 > 解决方案 > 如何禁止json模式数组中的某些anyOf项目多次出现

问题描述

考虑以下 json 模式:

{
    "type": "array",
    "items": {
        "anyOf":[
            { 
                "type": "object",
                "additionalProperties":false,
                "properties": {
                    "foo":{"type":"string"}
                }
            },
            {
                "type": "object",
                "additionalProperties":false,
                "properties": {
                    "bar":{"type":"number"}
                }
            }
        ]
    }
}

我怎么能指定,第一个模式anyOf可能会不确定地出现,但第二个模式可能只会出现一次?

下面的 json 应该是有效的,因为它只包含一个与第二个anyOf模式匹配的元素:

[
  {
    "foo":"hello"
  },
  {
    "foo":"world"
  },
  {
    "bar":42
  }
]

下面的 json 应该是无效的,因为它包含多个与第二个anyOf模式匹配的元素:

[
  {
    "foo":"hello"
  },
  {
    "foo":"world"
  },
  {
    "bar":42
  },
  {
    "bar":24
  }
]

我正在寻找任何 json-schema 草案版本的解决方案。

标签: arraysjsonvalidationjsonschema

解决方案


在草案 2019-09 和 2020-12 中,您可以使用++contains断言某些内容最多可以出现在数组中一次。minContainsmaxContains

{
  "type": "array",
  "items": {
    "anyOf": [
      { "$ref": "#/$defs/foo-string" },
      { "$ref": "#/$defs/foo-number" }
    ]
  },
  "contains": { "$ref": "#/$defs/foo-string" },
  "minContains": 0,
  "maxContains": 1
}

在draft-04-draft-07中,没有办法表达 contains-only-one。您可以做的最好的事情是要求只能出现一次的事物始终是数组的第一项。这表示第一项可以是“foo-string”或“foo-number”,其余的必须是“foo-number”。

{
  "type": "array",
  "items": [
    {
      "anyOf": [
        { "$ref": "#/$defs/foo-string" },
        { "$ref": "#/$defs/foo-number" }
      ]
    }
  ],
  "additionalItems": { "$ref": "#/definitions/foo-number" }
}

推荐阅读