Как упростить несколько операторов типа JSON-Schema - PullRequest
1 голос
/ 19 июня 2019

В документации по схеме JSON приведен пример условия, подобного переключателю.

https://json -schema.org / понимание-JSON-схема / ссылки / 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}" } }
      }
    }
  ]
}

1 Ответ

1 голос
/ 20 июня 2019

Вместо этого вы можете использовать шаблон enum.Это менее многословно и легче для чтения, но сообщения об ошибках, которые вы получаете, ужасны, поэтому я предлагаю вам придерживаться шаблона if / then.Вот как будет выглядеть шаблон enum.

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

Это позволяет кому-то понять все, что делает эта схема, просто прочитав первые несколько строк.Подробный / сложный материал выдвигается на дно, где вам не нужно иметь с ним дело, если вам не нужно.

...