【问题标题】:Removing the duplication in a JSON schema that uses oneOf (v4 or v5)删除使用 oneOf(v4 或 v5)的 JSON 模式中的重复项
【发布时间】:2017-06-09 19:15:50
【问题描述】:

我有一组 2 个属性,它们始终是可选的,但只有在另一个(始终需要)布尔属性的值为 true 时才允许存在。

总是可选但并不总是允许的属性被命名为:max_recurrencesrecurrence_arguments。它们所依赖的值为true 的布尔属性命名为:recurring

我想出了下面的架构,我认为它是可行的,但是我复制了oneOf 数组的每个项目中的所有其他属性。我正在寻找一种方法来避免这种重复。

{
  "id": "plan_schedule",
  "type": "object",
  "oneOf": [
    {
      "properties": {
        "start_date": {
          "type": "string",
          "format": "date-time"
        },
        "end_date": {
          "type": "string",
          "format": "date-time"
        },
        "trigger": {
          "$ref": "re_non_empty_string"
        },
        "arguments": {
          "type": "object",
          "minProperties": 1
        },
        "recurring": {
          "type": "boolean",
          "enum": [true],
        },
        "max_recurrences": {
          "type": "integer",
          "minimum": 1
        },
        "recurrence_arguments": {
          "type": "object",
          "minProperties": 1
        }
      }
    },
    {
      "properties": {
        "start_date": {
          "type": "string",
          "format": "date-time"
        },
        "end_date": {
          "type": "string",
          "format": "date-time"
        },
        "trigger": {
          "$ref": "re_non_empty_string"
        },
        "arguments": {
          "type": "object",
          "minProperties": 1
        },
        "recurring": {
          "type": "boolean",
          "enum": [false],
        },
      }
    }
  ],
  "additionalProperties": false,
  "required": ["start_date", "trigger", "recurring"]
}

谁能帮帮我?我想使用 v4,但如果有帮助,我愿意使用 v5。

为了进一步澄清,我希望只需要在整个架构中列出一次属性:start_dateend_datetriggerarguments

【问题讨论】:

    标签: json validation schema jsonschema


    【解决方案1】:

    JSON 架构草案-04:

    {
      "type": "object",
      "properties": {
        "recurring": {
          "type": "boolean"
        }
        // all other properties
      }
      "additionalProperties": false,
      "required": ["start_date", "trigger", "recurring"]
      "anyOf": [
        {
          "properties": { "recurring": { "enum": [true] } }
        },
        {
          "properties": { "recurring": { "enum": [false] } },
          "not": {
            "anyOf": [
              { "required": ["max_recurrences"] },
              { "required": ["recurrence_arguments"] }
            }
          }
        }
      ]
    }
    

    如果您使用 Ajv(我假设是因为 v5 是其他任何地方都没有使用的概念),您可以使用为 07 草案提出的自定义关键字“if/then/else”和“prohibited”来简化上述内容,并且有一些支持 - 它们在ajv-keywords 中定义。 "anyOf" 可以替换为:

    "if": { "properties": { "recurring": { "enum": [false] } } },
    "then": { "prohibited": ["max_recurrences", "recurrence_arguments"] }
    

    编辑:

    实际上,使用“dependencies”关键字可以更简单地完成,而无需任何自定义关键字。而不是“anyOf”:

    "dependencies": {
      "max_recurrences": { "$ref": "#recurring" },
      "recurrence_arguments": { "$ref": "#recurring" }
    },
    "definitions": {
      "recurring": {
        "id": "#recurring",
        "properties": {
          "recurring": { "enum": [true] }
        }
      }
    }
    

    【讨论】:

    • 看起来这个架构正在根据recurring 的值来决定recurrence_argumentsmax_recurrences 是否应该必需。这实际上不是我要找的。这些字段绝不应该是必需的,但如果 recurring 不是 true,则不应允许。
    • 你指的是哪个选项?
    • 您的编辑实际上看起来像我想要的那样,但如果recurring 为真,前 2 项看起来就像是必填字段。我弄错了吗?
    • 是的,已编辑,不再需要。最后可能是最好的。但第二个是最短且更容易阅读的:)
    • 还将 oneOf 替换为 anyOf - 除非您完全需要 oneOf,否则它总是更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    相关资源
    最近更新 更多