JSON 架构:条件依赖

JSON schema: conditional dependency

我似乎无法弄清楚如何在 JSON 模式中实现某些目标。假设我有两个字段:statusquote.

条件依赖如下:

我正在尝试使用以下架构实现此行为:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "quote": {
      "type": "string",
    },

    "status": {
      "type": "string",
      "enum": ["Y", "N", "M", "A", "S"]
    }
  },
  
  "oneOf": [
      {
        "properties": {
          "status": {"enum": ["Y", "N"]}
        },
        "required": [
          "quote"
        ]
      },
      {
        "properties": {
          "status": {"enum": ["Y", "N", "M", "A", "S"]}
        }
      }
  ]
}

前两个条件按预期工作,但只要 status 字段从 JSON 中遗漏,验证就会失败。想要的行为是,只要 status 字段不存在,我就可以拥有一个字段 quote

我怎样才能做到这一点?

更新

所以我设法实现了我最初的要求,但是,我现在有额外的要求。也就是说,我有一个额外的字段 author,只要 status["M", "A"] 就需要它,否则它只是可选的。如果 status 不存在,则 quoteauthor 都可以是任何值。我试过如下:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "quote": { "type": "string" },
    "author": { "type": "string" },
    "status": { "enum": ["Y", "N", "M", "A", "S"] }
  },
  "allOf": [
    { "$ref": "#/definitions/y-or-n-requires-quote" },
    { "$ref": "#/definitions/m-or-a-requires-author" }
  ],
  "definitions": {
    "y-or-n-requires-quote": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/status-is-y-or-n" } },
        { "required": ["quote"] }
      ]
    },
    "m-or-a-requires-author": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/status-is-m-or-a" } },
        { "required": ["author"] }
      ]
    },
    
    "status-is-y-or-n": {
      "properties": {
        "status": { "enum": ["Y", "N"] }
      }
    },
    
    "status-is-m-or-a": {
      "properties": {
        "status": { "enum": ["M", "A"] }
      }
    }
  }
}

但是,使用此架构不适用于 JSON,其中 status 不存在。

您需要使用称为蕴涵(!A 或 B)的布尔逻辑概念。这是表达 if-then 约束的一种方式。在这种情况下,我们想表达的是:要么status不是"Y"/"N"要么quote is required.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "quote": { "type": "string" },
    "status": { "enum": ["Y", "N", "M", "A", "S"] }
  },
  "allOf": [
    { "$ref": "#/definitions/y-or-n-requires-quote" }
  ],
  "definitions": {
    "y-or-n-requires-quote": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/status-is-y-or-n" } },
        { "required": ["quote"] }
      ]
    },
    "status-is-y-or-n": {
      "properties": {
        "status": { "enum": ["Y", "N"] }
      },
      "required": ["status"]
    }
  }
}

请注意,draft-07 添加了“if”/“then”/“else”关键字以简化条件判断:

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-00#section-6.6

如果您的工具不支持 draft-07,请考虑提交功能请求以更新它们:-)