如何简化多个 JSON-Schema switch-like 语句

How to simplify multiple JSON-Schema switch-like statements

JSON 架构文档中有一个类似开关条件的示例。

https://json-schema.org/understanding-json-schema/reference/conditionals.html

我在示例中又添加了两个国家/地区,这两个国家/地区的邮政编码模式应与荷兰相同。我可以让这个例子与两个额外的 if/then 结构一起工作,但是当要添加更多项目时它会变得混乱。

是否有DRYer版本,例如喜欢下面的假设吗?

"properties": { "country": { "const": ["Netherlands", "Upperlands", "Lowerlands" } }
{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada", "Netherlands",
              "Upperlands","Lowerlands"]
    }
  },
  "allOf": [
    {
      "if": {
        "properties": { "country": { "const": "United States of America" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Canada" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Netherlands" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
      }
    }
  ]
}

您可以改用枚举模式。它不那么冗长也更容易阅读,但是你得到的错误信息很糟糕,所以我建议你坚持使用 if/then 模式。这是使用枚举模式的样子。

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada", "Netherlands",
               "Upperlands","Lowerlands"]
    }
  },
  "anyOf": [
    {
      "properties": {
        "country": { "const": "United States of America" },
        "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" }
      }
    },
    {
      "properties": {
        "country": { "const": "Canada" },
        "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" }
      }
    },
    {
      "properties": {
        "country": { "const": "Netherlands" },
        "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" }
      }
    }
  ]
}

虽然没有解决冗长的好方法,但您可以做一些改进 readability/maintainability。您可以使用定义来隐藏冗长的部分。

{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "enum": ["United States of America", "Canada", "Netherlands",
               "Upperlands","Lowerlands"]
    }
  },
  "allOf": [
    { "$ref": "#/definitions/validate-us-postal-code" },
    { "$ref": "#/definitions/validate-ca-postal-code" },
    { "$ref": "#/definitions/validate-nl-postal-code" }
  ]
  "definitions": {
    "validate-us-postal-code": {
      "if": {
        "properties": { "country": { "const": "United States of America" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
      }
    },
    "validate-ca-postal-code": {
      "if": {
        "properties": { "country": { "const": "Canada" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
      }
    },
    "validate-nl-postal-code": {
      "if": {
        "properties": { "country": { "const": "Netherlands" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
      }
    }
  }
}

这使得某人仅通过阅读前几行就能够理解该架构所做的一切。 verbose/complicated 东西被推到底部,如果你不需要,你不必处理它。