Json 架构在 if 条件上添加属性

标签 json jsonschema

在 JSON 架构中,我想添加一个验证,判断负载是否与下面匹配

{
   "key1": "value1", 
   "key1": "value2"
}

然后期望第三个键“key3”具有任意值。

但如果 key1 和 key2 的值​​分别与 value1、value2 不匹配,则 key3 不应出现。

JSON 架构如下所示

{
  "$async": true,
  "additionalProperties": false,
  "properties": {
    "key1": {
      "type": "string"
    }, 
    "key2": {
      "type": "string"
    }
  },
  "required": ["key1"],
  "allOf": [
    {
      "if": {
        "properties": {
          "key1": {
            "const": "value1"
          }, 
          "key2": {
            "const": "value2"
          }
        }
      },
      "then": {
        "properties": {
          "key3": {
            "type": "string"
          }
        },
        "required": ["key3"]
      },
      "else": {
      }
    }
  ]
}

有效输入是

{
   "key1": "value1", 
   "key2": "value2", 
   "key3": "some-value"
}
--------
{
    "key1": "value1", 
    "key2": "other-value"
}
---------
{
    "key1": "value1"
}
---------
{
    "key1": "other-value", 
    "key2": "value2"
}
---------
{
    "key1": "other-value1", 
    "key2": "other-value2"
}

无效输入

{
   "key1": "value1", 
   "key2": "value2".   // key3 should be present
}
--------
{
   "key1": "hello", 
   "key2": "world",  
   "unexpected-key": "value"   // Any other key should not be allowed 
}
--------
{
    "key1": "value1", 
    "key2": "other-value", 
    "key3": "abc"    // should not be present
 
}
---------
{
    "key1": "other-value", 
    "key2": "value2",
    "key3": "abc"    // should not be present
}
---------
{
    "key1": "other-value1", 
    "key2": "other-value2",
    "key3": "abc"    // should not be present
}

对于以下有效负载,JSON schema validator

{
  "key1": "value1", 
  "key2": "value2", 
  "key3": "abc"
}

抛出以下错误

Property 'key3' has not been defined and the schema does not allow additional properties.

如何实现此条件属性?

最佳答案

解决方案取决于您能够使用 JSON 架构的版本(或“草案”)。 2019-09 草案或更高版本提供了更清晰的解决方案,但在 07 草案中仍然有可能。

(在使用 implication method 引入 if/then/else 之前也是可能的,但今天我不会讨论这个。

使用 2019-09 或 2020-12 的最佳解决方案。

unevaluatedProperties 关键字可以“透视”应用程序关键字,例如 allOfifelse

与 Draft-07 的 additionalProperties 不同,unevaluatedProperties 在架构架构对象中的所有其他应用程序之后运行,并且可以了解在更深层次的嵌套应用程序中定义的已成功验证的属性值。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "unevaluatedProperties": false,
  "properties": {
    "key1": {
      "type": "string"
    },
    "key2": {
      "type": "string"
    }
  },
  "required": [
    "key1"
  ],
  "allOf": [
    {
      "if": {
        "required": ["key2"],
        "properties": {
          "key1": {
            "const": "value1"
          },
          "key2": {
            "const": "value2"
          }
        }
      },
      "then": {
        "required": ["key3"],
        "properties": {
          "key3": {
            "type": "string"
          }
        }
      }
    }
  ]
}

对于测试 2019-09 及更高版本的草案,我建议使用 https://json-schema.hyperjump.io Playground

( https://jsonschema.dev 尚不支持 2019-09 及更高版本的草案)。

使用 Draft-07 的解决方案。

要使 additionalProperties: false 正常工作,需要在 properties 中的同一架构对象中定义属性(或匹配 patternProperties) .

在第一个实例中,您不关心具体值,properties 对象中的值只是true。值验证稍后处理。如果您觉得更干净,可以将其移至顶层。

通过此更改,我们的 if/then 可以按照您的示例进行工作,除了它没有阻止 key3 时,它应该有。我们通过在 else 中使用 not 来解决这个问题。

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "additionalProperties": false,
  "properties": {
    "key1": {
      "type": "string"
    }, 
    "key2": {
      "type": "string"
    },
    "key3": true
  },
  "required": ["key1"],
  "allOf": [
    {
      "if": {
        "required": ["key2"],
        "properties": {
          "key1": {
            "const": "value1"
          }, 
          "key2": {
            "const": "value2"
          }
        }
      },
      "then": {
        "required": ["key3"],
        "properties": {
          "key3": {
            "type": "string"
          }
        }
      },
      "else": {
        "not": {
          "required": ["key3"]
        }
      }
    }
  ]
}

演示:https://jsonschema.dev/s/ZTi4X

关于Json 架构在 if 条件上添加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69303838/

相关文章:

android - 在 Android 中解析 JSON 数据的最佳方式是什么?

c# - 使用 JSchema 进行模式验证的时间问题

swagger - JSON模式到GraphQL模式转换器

java - Hibernate 延迟加载抛出 JsonMappingException

java - Android/Java - Gson 从 JSON 字符串解析为对象 - 日期问题

python - 如何使 json-schema 允许一个字段而不是另一个字段?

javascript - 如何使用 json 模式文件测试 json 文件

JSON Schema oneOf 属性已填充

javascript - 是否可以将 localStorage JSON 文件存储或导出到磁盘?

javascript - 如何在此 JSON 文件中引用此数据?