如何简化多个类似JSON-Schema开关的语句

时间:2019-06-19 08:24:51

标签: json jsonschema

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

1 个答案:

答案 0 :(得分:1)

您可以改用枚举模式。它不那么冗长,更易于阅读,但是收到的错误消息却很糟糕,因此我建议您坚持使用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}" }
      }
    }
  ]
}

尽管没有很多方法可以解决冗长的问题,但是您可以采取一些措施来提高可读性/可维护性。您可以使用定义来隐藏详细部分。

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

这使某人仅需阅读前几行就能了解该模式的所有内容。冗长/复杂的内容被推到底部,如果不需要,则无需处理。