json - 如何根据 JSON Schema 中其他属性的存在有条件地禁止属性?
问题描述
在我的模式中,我声明了这些属性:
"index_name": {
"type": "string",
"examples": ["foo-wwen-live", "foo"]
},
"locale": {
"type": "string",
"examples": ["wwen", "usen", "frfr"]
},
"environment": {
"type": "string",
"default": "live",
"examples": [
"staging",
"edgengram",
"test"
]
}
我希望针对我的架构验证的 JSON 正文仅在以下情况下有效:
index_name
存在,并且两者都不 存在;locale
environment
locale
和/或enviroment
存在,index_name
不存在
简而言之,locale
绝不environment
应与index_name
.
测试用例和期望的结果:
这些应该通过:
案例#1
{
"locale": "usen"
}
案例#2
{
"environment": "foo"
}
案例#3
{
"environment": "foo",
"locale": "usen"
}
案例#4
{
"index_name": "foo-usen"
}
这些不应该通过:
案例#5
{
"index_name": "foo-usen",
"locale": "usen"
}
案例#6
{
"index_name": "foo-usen",
"environment": "foo"
}
案例#7
{
"index_name": "foo-usen",
"locale": "usen",
"environment": "foo"
}
我为我的架构创建了以下规则,但它并不涵盖所有情况。例如,如果locale
和environment
都存在,如果也存在,则验证返回失败index_name
,根据案例 #7,这是正确的行为。但是如果只有一个locale
andenvironment
存在,它也允许index_name
存在(在 #5 和 #6 的情况下失败)。
"oneOf": [
{
"required": ["index_name"],
"not": {"required": ["locale", "environment"]}
},
{
"anyOf": [
{
"required": ["locale"],
"not": {"required": ["index_name"]}
},
{
"required": ["environment"],
"not": {"required": ["index_name"]}
}
]
}
]
我得到了关于"not": {"required": []}
声明如何工作的混合信息。有些人声称这意味着它禁止在数组中声明的任何内容存在,这与语法给出的想法相反。其他人声称这应该完全按照听起来:数组中列出的属性不是必需的- 它们可以存在,但如果它们不存在也没关系。
除了这条规则,我还要求在所有情况下都存在一个不相关的属性,并且我设置了"additionalProperties": false
.
满足我所有测试用例的规则是什么?
解决方案
依赖项
这是dependencies
关键字的工作。下面说
- 如果存在“locale”,则禁止使用“index_name”。
- 如果存在“环境”,则禁止“索引名称”。
|
"dependencies": {
"locale": { "not": { "required": ["index_name"] } },
"environment": { "not": { "required": ["index_name"] } }
}
怎么了not
- required
?
not
有一个关于如何工作的子问题required
。这很令人困惑,因为它并不意味着它在英语中的阅读方式,但它的相似性足以让我们有时认为它确实如此。
在上面的例子中,如果我们把它读作“不需要”,听起来它的意思是“可选的”。更准确的描述是“禁止”。
这很尴尬,但也不算太糟糕。当您想要“禁止”多个属性时,它会变得令人困惑。假设我们想说,如果“foo”存在,那么“bar”和“baz”是被禁止的。你可以尝试的第一件事就是这个。
"dependencies": {
"foo": { "not": { "required": ["bar", "baz"] } }
}
但是,这说明如果“foo”存在,那么如果“bar”和“baz”都存在,则实例无效。他们都必须在那里触发失败。我们真正想要的是,如果存在“bar”或“baz”,它就无效。
"dependencies": {
"foo": {
"not": {
"anyOf": [
{ "required": ["bar"] },
{ "required": ["baz"] }
]
}
}
}
为什么这么难?
JSON Schema 针对可容忍更改的模式进行了优化。模式应该强制实例具有完成特定任务所需的数据。如果它有超过它需要的,应用程序忽略其余的。这样,如果将某些内容添加到实例中,一切仍然有效。如果实例有一些应用程序不使用的额外字段,它不应该验证失败。
因此,当您尝试执行诸如禁止您原本可以忽略的事情之类的事情时,您会有点违背 JSON Schema 的原则,事情会变得有些难看。但是,有时它是必要的。我对您的情况了解不多,无法拨打电话,但我想dependencies
在这种情况下这可能是必要的,但additionalProperties
不是。
推荐阅读
- mysql - SQL ORDER BY 使用另一个表中的值使用按重复项分组的公式
- javascript - 没有物品时如何设置购物车状态?
- asp.net-core - Asp.net Core SignalR 集线器检查连接是否处于活动状态而不是向它们发送文本
- react-native - React Native using NativeBase - 是否可以在 Accordion 内容中显示和自定义具有多个数据集的数组?
- node.js - “nestjs/swagger”中的哪个函数将 DTO 转换为 Swagger 模型定义?
- javascript - 从 PHP 转换后无法读取未定义 Javascript 错误的属性“0”
- sql - 根据当前值更新上一行
- spring-boot - 通过功能标志控制 spring jersey 应用程序到 webflux 的迁移
- flash - Flash 8 key.isDown 代码
- javascript - 如何更改待办事项列表中未来元素的 css?