【问题标题】:How to make anyOf a set of mutually exclusive properties except one如何使 anyOf 一组互斥的属性,除了一个
【发布时间】:2014-06-20 14:55:11
【问题描述】:

我有一个我试图在 JSON 模式中定义的遗留 API,并且该对象有一个奇怪的结构,其中有一组 4 个属性,其中任何一个都是必需的,其中 3 个是互斥的。之后还有 30 多个共享可选属性,我将它们记为 ...

例如,

{ "foo": "bar", "baz": 1234, ... }  // OK
{ "foo": "bar", "buzz": 1234, ... } // OK
{ "foo": "bar", "fizz": 1234, ... } // OK
{ "foo": 1234, ... }                // OK
{ "baz": 1234, ... }                // OK
{ ... }                             // NOT OK
{ "baz": 1234, "buzz": 1234, ... }  // NOT OK

我可以做一个oneOf,但这不允许foo与其他人一起出现,anyOf允许bazbuzzfizz彼此出现,这是不可能的。

我尝试定义如下内容:

{
    "type": "object",
    "properties": {
        "foo": {"type": "string"},
        "baz": {"type": "number"},
        "buzz": {"type": "number"},
        "fizz": {"type": "number"}
    },
    "anyOf": [
        {"required": ["foo"]},
        {"required": [{"oneOf": [
                {"required": ["baz"]},
                {"required": ["buzz"]},
                {"required": ["fizz"]}
            ]}
        ]}            
    ]
}

{
    "type": "object",
    "properties": {
        "foo": {"type": "string"},
        "baz": {"type": "number"},
        "buzz": {"type": "number"},
        "fizz": {"type": "number"}
    },
    "anyOf": [
        {"required": ["foo"]},
        {"oneOf": [
                {"required": ["baz"]},
                {"required": ["buzz"]},
                {"required": ["fizz"]}
            ]
        }            
    ]
}

但这不起作用,我只是对 json 架构了解不够,还不知道这是否可能。

【问题讨论】:

    标签: json jsonschema


    【解决方案1】:

    有趣!可能有一个更简洁的解决方案,但我们开始......

    “互斥”约束可以通过禁止属性的成对组合来表示:

    {
        "not": {
            "anyOf": [
                {"required": ["baz", "buzz"]},
                {"required": ["buzz", "fizz"]},
                {"required": ["fizz", "baz"]}
            ]
        }
    }
    

    “至少一个”约束可以用anyOf表示:

    {
        "anyOf": [
            {"required": ["foo"]},
            {"required": ["baz"]},
            {"required": ["buzz"]},
            {"required": ["fizz"]}
        }
    }
    

    如果您只是将这两个约束组合到一个模式中,那么它应该可以工作:

    {
        "not": {"anyOf": [...]},
        "anyOf": ...
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用成对排除在 JSON Schema 中使属性互斥,但这会导致组合爆炸。当您有许多互斥属性时,这将成为一个问题。

      线性解的形式为:

      • 之一:
        • 属性a
        • 属性 b
        • 属性 c
        • 不是任何一个:
          • 属性a
          • 属性 b
          • 属性 c

      只有在您拥有许多房产的情况下才能获得回报。

      { "oneOf": [
        { "required": ["baz"] },
        { "required": ["buzz"] },
        { "required": ["fizz"] },
        { "not":
          { "anyOf": [
            { "required": ["baz"] },
            { "required": ["buzz"] },
            { "required": ["fizz"] }
          ] }
        }
      ] }
      

      将此与@cloudfeet 的答案结合起来,以获得您特定问题的答案。

      【讨论】:

      • 这可能是最好的答案。
      • 不错! :) 是的,这样可以更好地扩展。
      猜你喜欢
      • 2018-11-25
      • 2011-12-26
      • 2020-08-29
      • 1970-01-01
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多