【问题标题】:requiring a param with JSON Schema when another param is not present当另一个参数不存在时,需要一个带有 JSON Schema 的参数
【发布时间】:2020-09-28 01:15:43
【问题描述】:

更新:添加要求

我正在尝试实现一个像这样工作的 JSON 模式……

给定以下参数:foobarbazonetwo

以下其中一项应适用

  • 不存在任何参数
  • 如果存在一个或多个参数,则
    • 如果存在foo - 那么onetwo 不需要
    • else 如果存在除foo 之外的任何参数 - 那么onetwo 是必需的

当然,如果提供的 任何 参数在架构中,则应引发适当的错误。

经过大量的摸索,inspiration,这是我的尝试,它并没有真正奏效

{
    "type": "object",
    "properties": {
        "foo": { "type": "string" },
        "bar": { "type": "string" },
        "baz": { "type": "string" }
    },
    "oneOf": [
        {
            "not": {
                "properties": { "foo": { "const": "" } },
                "required": []
            }
        },
        { "required": [ "one", "two" ] }
    ]
}

我也尝试了以下方法,但没有成功

{
    "type": "object",
    "properties": {
        "foo": { "type": "string" },
        "bar": { "type": "string" },
        "baz": { "type": "string" }
    },
    "dependencies": {
        "not": {
            "foo": { "required": ["one", "two"] }
        }
    }
}

【问题讨论】:

  • fooone/two 是否互斥?
  • 如果没有barbaz,是否禁止onetwo,或者只是可选的?

标签: jsonschema


【解决方案1】:

我怀疑这里可能有一两个隐藏的要求,但这里有一个基于您的要求的解决方案。如果我遗漏了什么,请告诉我,我会更新我的答案。

您的大部分要求都是 JSON Schema 中的默认行为,因此您无需执行任何操作。

  • 不存在任何参数

默认情况下所有属性都是可选的,所以这里什么都不做

  • 如果 foo 存在 - 则不需要一和二

同样,可选是默认设置,所以这里什么都不做

  • 如果存在一个或多个参数,则 [并且] 存在除 foo 之外的任何参数 - 则需要一个和两个

表达这一点的最佳方式是使用if/then。如果“foo”是可选的,那么表达“foo 以外的任何参数”会有点复杂,所以我把它放在definitions 中以便于阅读。

如果提供的任何参数不在架构中,则应引发适当的错误。

additionalProperties 关键字可以解决这个问题。您只需添加“一”和“二”即可。

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" },
    "baz": { "type": "string" },
    "one": {},
    "two": {}
  },
  "additionalProperties": false,
  "if": { "$ref": "#/definitions/has-property-other-than-foo" },
  "then": { "required": ["one", "two"] },
  "definitions": {
    "has-property-other-than-foo": {
      "if": { "required": ["foo"] },
      "then": { "minProperties": 2 },
      "else": { "minProperties": 1 }
    }
  }
}

【讨论】:

  • 我接受了你的回答,然后因为我意识到它有一个(不方便的)问题而没有接受它。为了便于讨论,我们将 foo 称为主键。如果 PK 不存在,则 "anyOf" 条件将每个非 PK 属性列在单独的行上,例如 { "required": ["bar"] }。我的架构有很多(25-30)个这样的非 PK 属性。有没有办法在这个"anyOf" 子句中说“除了'foo'之外的所有东西”?
  • 是的,它有效。非常感谢。我已将您的答案标记为已接受。如果我能再请你一个忙。您能否解释一下"has-property-other-than-foo" 块中到底发生了什么?我正在尝试转换为简单的英语,但按照我的逻辑,“如果需要 'foo',则 minProperties 应该为 1”(也就是说,不应允许其他任何内容)。或者,它可能意味着“如果存在‘foo’,那么‘必需’属性的数量应该是 2,否则它们应该是 0”。但这些似乎都没有被“has-property-other-than-foo”块所暗示。它确实有效,为此,赞!
  • 如果对象有一个名为“foo”的属性并且至少有2个属性,则意味着它必须有一个“foo”以外的属性。如果对象没有名为“foo”的属性并且至少有 1 个属性,则意味着它必须具有“foo”以外的属性。希望对您有所帮助。
猜你喜欢
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
相关资源
最近更新 更多