将 oneOf 嵌套在 anyOf 中以获得 JSON 模式

Nesting oneOf in anyOf for a JSON Schema

这里是 JSON 架构和下面 link 中提供的 JSON 用于说明目的。

JSON Schema and the JSON

格式: 数组中的单个 JSON 对象(及其附加属性可能会随数组中的其他对象而变化)可以是任何 3 个区域:'america'、'asia' 和 'europe' 以及至少应该存在区域对象的类型。这可以通过数组 minItems 属性)

来实现

问题陈述:

  1. 数组中的单个 JSON 对象可以是任何 3 个区域:'america'、'asia' 和 'europe' 并且至少在区域对象的类型应该存在

    ==> 我可以通过将所有区域对象放入 anyOf 数组来解决这个问题,因为我想匹配至少一个有效区域对象。

  2. JSON 对象 'asia' 或 'europe' 可以与其他区域类型一起存在。两者不能共存。

    ==> 我尝试使用 'oneOf' 但它通过了 ajv 验证。实际上它应该失败。谁能帮忙。谢谢

JSON 架构

{
    "type": "object",
    "properties": {
        "stat_data": {
            "type": "array",
            "minItems": 1,
            "items": {
                "type": "object",
                "properties": {},
                "anyOf": [{
                        "required": ["region"],
                        "properties": {
                            "region": {
                                "enum": ["america"]
                            },
                            "country": {
                                "type": "string"
                            },
                            "population": {
                                "type": "string"
                            }
                        }
                    },
                    {
                        "oneOf": [
                            {
                                "required": ["region"],
                                "properties": {
                                    "region": {
                                        "enum": ["asia"]
                                    },
                                    "country": {
                                        "type": "string"
                                    },
                                    "details": {
                                        "type": "object",
                                        "properties": {
                                            "language": {
                                                "type": "string"
                                            },
                                            "tz": {
                                                "type": "string"
                                            }
                                        }
                                    }
                                }
                            }, {
                                "required": ["region"],
                                "properties": {
                                    "region": {
                                        "enum": ["europe"]
                                    },
                                    "country": {
                                        "type": "string"
                                    },
                                    "language": {
                                        "type": "string"
                                    }
                                }
                            }
                        ]
                    }
                ]
            }
        }
    }
}

JSON 对象失败,因为 "asia" 和 "europe" 类型的对象不能共存。

{
    "stat_data": [{
            "region": "america",
            "country": "USA",
            "states": "50"
        }, {
            "region": "asia",
            "country": "Japan",
            "details": {
                "language": "Japanese",
                "tz": "utc+9.00"
            }
        }, {
            "region": "europe",
            "country": "finland",
            "language": "Finnish"
        }
    ]
}

JSON 要通过的对象仅存在 "asia" 类型对象。

{
    "stat_data": [{
            "region": "america",
            "country": "USA",
            "states": "50"
        }, {
            "region": "asia",
            "country": "Japan",
            "details": {
                "language": "Japanese",
                "tz": "utc+9.00"
            }
        }
    ]
}

JSON 要通过的对象仅存在 "europe" 类型对象。

{
    "stat_data": [{
            "region": "america",
            "country": "USA",
            "states": "50"
        }, {
            "region": "europe",
            "country": "finland",
            "language": "Finnish"
        }
    ]
}

我明白你为什么尝试你所做的方法,但是它没有按预期工作,因为你已经定义了数组中的每个项目可能是 america 或(europeasia),这不是你想要的。

请记住,items 将值架构应用于数组中的每个元素。它对整个数组本身没有任何限制。 contains 检查数组中的至少一项是否根据其值架构进行验证。

你想说的是,数组中的每一项可能有americaeuropeasia,但数组中可能不包含europe如果包含 asia 和相反的

我重构了架构并做了一些更改。

希望您也能清楚地看到使用 oneOf >> (containsnot > contains) 的意图。

JSON 架构通过添加约束来工作。您通常不能通过省略来定义约束。

JSON Schema and data validation demo

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "containtsAsia": {
      "contains": {
        "properties": {
          "region": {
            "const": "asia"
          }
        }
      }
    },
    "containsEurope": {
      "contains": {
        "properties": {
          "region": {
            "const": "europe"
          }
        }
      }
    }
  },
  "type": "object",
  "properties": {
    "stat_data": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "region": {
            "enum": [
              "america",
              "asia",
              "europe"
            ]
          },
          "country": {
            "type": "string"
          },
          "population": {
            "type": "string"
          }
        }
      },
      "oneOf": [
        {
          "allOf": [
            {
              "$ref": "#/definitions/containtsAsia"
            },
            {
              "not": {
                "$ref": "#/definitions/containsEurope"
              }
            }
          ]
        },
        {
          "allOf": [
            {
              "$ref": "#/definitions/containsEurope"
            },
            {
              "not": {
                "$ref": "#/definitions/containtsAsia"
              }
            }
          ]
        }
      ]
    }
  }
}