【问题标题】:JSON Schema: Conditionally require property depending on several properties' valuesJSON Schema:根据几个属性的值有条件地需要属性
【发布时间】:2021-01-25 05:23:10
【问题描述】:

我想使用 JSON 模式验证 JSON 文件,应该需要几个“属性”,具体取决于其他属性的值。

示例

  • 具有“A”、“B”、“C”和“D”属性
  • 如果“A”的值为“foo”,则需要 C
  • 如果“B”的值为“foo”,则需要 D
  • 如果“A”和“B”都具有值“foo”,则 C 和 D 都是必需的
  • 否则,什么都不需要

我在这里看到了一个非常有用的答案:https://stackoverflow.com/a/38781027/5201771 --> 在那里,作者针对单个属性的情况解决了这个问题(例如,只有“A”的值是“foo”,所以需要"C")。

但是,我目前不知道如何将该答案扩展到我的案例,其中几个属性决定了结果。

示例文件

为了说明,我提供了一些应该通过或未通过验证的文件:

应该通过:

{
    "A": "bar"
    "B": "baz"
}
{
    "A": "foo"
    "C": "some value"
}
{
    "A": "bar"
    "B": "foo"
    "D": "some value"
}

应该失败:

{
    "A": "foo"
    "B": "foo"
    "D": "some value"
}

【问题讨论】:

    标签: jsonschema


    【解决方案1】:

    您可以通过多种方式组合条件,但将它们与allOf 组合通常是最好的方式。

    {
      "type": "object",
      "properties": {
        "A": {},
        "B": {},
        "C": {},
        "D": {}
      },
      "allOf": [
        { "$ref": "#/definitions/if-A-then-C-is-required" },
        { "$ref": "#/definitions/if-B-then-D-is-required" }
      ],
      "definitions": {
        "if-A-then-C-is-required": {
          "if": {
            "type": "object",
            "properties": {
              "A": { "const": "foo" }
            },
            "required": ["A"]
          },
          "then": { "required": ["C"] }
        },
        "if-B-then-D-is-required": {
          "if": {
            "type": "object",
            "properties": {
              "B": { "const": "foo" }
            },
            "required": ["B"]
          },
          "then": { "required": ["D"] }
        }
      }
    }
    

    【讨论】:

    • 这似乎可行,谢谢!令我惊讶的是,来自“allOf”的条件“必需”项目都集成到了一个整体(不可见)“必需”项目列表中(这就是我想要的,太棒了!)。此外,如果我已经在“属性”之后明确定义了一个“必需”的项目列表,那么该列表也会得到扩展(也是我想要的!)。然而,令人惊讶的是,因为如果我改为在 JSON 模式中多次定义“必需”,则几个“必需”语句不会被集成:只有这些“必需”中的一个被选中,并且其他被丢弃。
    • 每个“必需”关键字在针对数据进行评估时都会被单独考虑。 JSON 结构的本质意味着一个关键字只能在其直接数据结构中出现一次,但是如果您以多个子模式可以应用于同一实例位置的方式编写模式(例如使用 if/then 和 allOf,等)然后您可以在每个位置使用相同的关键字,以便拥有多个规则。
    猜你喜欢
    • 1970-01-01
    • 2015-09-01
    • 2020-07-18
    • 1970-01-01
    • 2016-12-07
    • 2012-07-28
    • 2020-06-03
    • 1970-01-01
    相关资源
    最近更新 更多