代码之家  ›  专栏  ›  技术社区  ›  Dieter Menne

如何简化多个类似json模式开关的语句

  •  1
  • Dieter Menne  · 技术社区  · 7 年前

    json模式文档中有一个类似开关的条件示例。

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

    我在示例中又添加了两个国家,这两个国家的邮政编码模式应该与荷兰相同。我可以让这个例子与另外两个 if/then 结构,但如果要添加更多项,则会变得混乱。

    是否有烘干机版本,例如下面的假设版本?

    "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}" } }
          }
        }
      ]
    }
    
    
    0 回复  |  直到 7 年前
        1
  •  1
  •   Jason Desrosiers    7 年前

    您可以改用枚举模式。它不那么冗长,也更容易阅读,但是您得到的错误消息非常糟糕,所以我建议您坚持使用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}" } }
          }
        }
      }
    }
    

    这使得有人能够通过阅读前几行来理解这个模式所做的一切。冗长/复杂的事情被推到最底层,如果你不需要的话,你就不必处理它。