【问题标题】:How to forbid certain anyOf items in json schema array to occur more than once如何禁止json模式数组中的某些anyOf项目多次出现
【发布时间】:2021-02-24 20:38:49
【问题描述】:

考虑以下 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 草案版本的解决方案。

【问题讨论】:

    标签: arrays json validation jsonschema


    【解决方案1】:

    在 2019-09 和 2020-12 草案中,您可以使用 contains + minContains + maxContains 断言数组中最多只能出现一次。

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

    【讨论】:

    • 这行得通,谢谢!我想我可以使用最新的草稿。不要把这推得太远,但你有没有找到一种方法来适应它,所以几个 anyOf 模式可以限制为最多一个外观?
    • 如果我理解正确,您想添加额外的 contains 约束。如果您需要在模式中多次使用相同的关键字,则可以使用allOf"allOf": [{ "contains": { ... } }, { "contains": { ... } }]
    • 是的,就是这样!
    猜你喜欢
    • 2016-12-26
    • 2015-12-31
    • 1970-01-01
    • 2015-04-24
    • 2021-10-26
    • 1970-01-01
    • 2014-10-16
    • 2012-11-15
    相关资源
    最近更新 更多