有没有一种方法可以使用 JSON SCHEMA 为我的属性按值声明依赖关系?

Is there a way I can declare a dependency by value for my properties using JSON SCHEMA?

假设我们有一个简单的对象,例如:

{ "key_1": "value_1", "key_2": "value_2" }

有没有一种方法可以通过声明基于它们的值的键间依赖关系来制作我的 json 模式,这样它就不允许在 key_2 中重复 value_1?我正在使用 json 架构 draft-4

不允许:

{ "key_1": "value_1", "key_2": "value_1" }

首先:如果键 and/or 值预先未知,则属于 "business logic" 类别,这超出了 JSON 模式规范的范围,并且需要独立处理。


根据您的评论,值的数量是有限的(我假设键也是如此)。这意味着你有几个选择——即使是在草案 4 中。

1。使用 anyOf 确保除一个键外的所有键都没有特定值,最后将其包装在 allOf 中(对于每个值)。

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "key_1": { "type": "string" },
    "key_2": { "type": "string" },
    "key_3": { "type": "string" }
  },
  "allOf": [
    {
      "anyOf": [
        {
          "properties":{
            "key_1": { "not": { "enum": ["value_1"] } },
            "key_2": { "not": { "enum": ["value_1"] } }
          }
        },
        {
          "properties":{
            "key_1": { "not": { "enum": ["value_1"] } },
            "key_3": { "not": { "enum": ["value_1"] } }
          }
        },
        {
          "properties":{
            "key_2": { "not": { "enum": ["value_1"] } },
            "key_3": { "not": { "enum": ["value_1"] } }
          }
        }
      ]
    },
    {
      "anyOf": [
        {
          "properties":{
            "key_1": { "not": { "enum": ["value_2"] } },
            "key_2": { "not": { "enum": ["value_2"] } }
          }
        },
        {
          "properties":{
            "key_1": { "not": { "enum": ["value_2"] } },
            "key_3": { "not": { "enum": ["value_2"] } }
          }
        },
        {
          "properties":{
            "key_2": { "not": { "enum": ["value_2"] } },
            "key_3": { "not": { "enum": ["value_2"] } }
          }
        }
      ]
    }
  ]
}

2。使用 oneOf 表示 none 或只有一个键具有特定值。对每个可能的值都这样做,最后将其包装在 allOf.

注意 required 关键字以确保相应的键确实存在。

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "key_1": { "type": "string" },
    "key_2": { "type": "string" },
    "key_3": { "type": "string" }
  },
  "allOf": [
    {
      "oneOf": [
        {
          "properties": {
            "key_1": { "not": { "enum": ["value_1"] } },
            "key_2": { "not": { "enum": ["value_1"] } },
            "key_3": { "not": { "enum": ["value_1"] } }
          }
        },
        {
          "properties": {
            "key_1": { "enum": ["value_1"] }
          },
          "required": ["key_1"]
        },
        {
          "properties": {
            "key_2": { "enum": ["value_1"] }
          },
          "required": ["key_2"]
        },
        {
          "properties": {
            "key_3": { "enum": ["value_1"] }
          },
          "required": ["key_3"]
        }
      ]
    },
    {
      "oneOf": [
        {
          "properties": {
            "key_1": { "not": { "enum": ["value_2"] } },
            "key_2": { "not": { "enum": ["value_2"] } },
            "key_3": { "not": { "enum": ["value_2"] } }
          }
        },
        {
          "properties": {
            "key_1": { "enum": ["value_2"] }
          },
          "required": ["key_1"]
        },
        {
          "properties": {
            "key_2": { "enum": ["value_2"] }
          },
          "required": ["key_2"]
        },
        {
          "properties": {
            "key_3": { "enum": ["value_2"] }
          },
          "required": ["key_3"]
        }
      ]
    }
  ]
}

可能还有更多组合,例如列出所有允许的值组合,但您明白了:对于一些键和值,这是可以管理的,但很快就会变得笨拙——假设您必须手动维护它。