如何使用可选的布尔值 属性 作为需要另一个 属性 的提示?
How do I use an optional boolean property as a hint to require another property?
想象一个 JSON 文档只有两个可能的属性:
persist
:布尔标志。默认为 true
dbName
: 一个字符串。
当 persist
为 true
时,dbName
属性 必须 出现在文档中。当 persist
为 false
时,dbName
属性 必须 而不是 文档。
看起来很简单——这是我想出的模式:
{
"description": "Example",
"$id": "https://example.com/example",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"persist": {
"type": "boolean"
},
"dbName": {
"type": "string"
}
},
"additionalProperties": false,
"oneOf": [
{
"$comment": "persist attr is present and == false, dbName should not be present",
"properties": {
"persist": {
"enum": [
false
]
}
},
"not": {
"required": [
"dbName"
]
}
},
{
"$comment": "persist attr is present and == true, require dbName",
"properties": {
"persist": {
"enum": [
true
]
}
},
"required": [
"dbName"
]
},
{
"$comment": "persist attr is missing, its default value is true, require dbName",
"properties": {
"persist": false
},
"required": [
"dbName"
]
}
]
}
它几乎 有效。三个测试文件来练习三种可能的情况:
{ "persist": true, "dbName": "dn" }
--> 有效
{ "persist": false }
--> 有效
{ "dbName": "dn" }
--> 无效,错误如下:
[{
keyword: 'not',
dataPath: '',
schemaPath: '#/oneOf/0/not',
params: {},
message: 'should NOT be valid'
},
{
keyword: 'oneOf',
dataPath: '',
schemaPath: '#/oneOf',
params: {
passingSchemas: [Array]
},
message: 'should match exactly one schema in oneOf'
}
]
通过反复试验,很明显最后一个文档实际上匹配 oneOf
中的两个条件:oneOf/1
和 oneOf/2
。
我不知道为什么它会匹配 oneOf/1
,因为 json 文档中没有 persist
属性。我确定我遗漏了一些明显的东西,非常感谢任何帮助。
在您对 oneOf
子模式的评论中,您曾说过您希望模式验证 persist
属性是否存在,但它没有。
我们来看看为什么会这样……
Validation succeeds if, for each name that appears in both the
instance and as a name within this keyword's value, the child
instance for that name successfully validates against the
corresponding schema.
https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.5.4
这意味着,如果相应的键存在,值子模式将应用于对象中的实例值。如果没有,则不应用。
因此,如果您从 oneOf/1
和 oneOf/2
中减去 properties
,它们是等价的子模式。
你想要 oneOf/2
的是...
{
"$comment": "persist attr is present and == true, require dbName",
"properties": {
"persist": {
"const": true
}
},
"required": [
"persist",
"dbName"
]
}
这是一个演示:https://jsonschema.dev/s/cqMDM
您也需要对 oneOf/0
进行相同的更改。
如果您没有按要求指定persist
,子模式将不会检查键是否存在。
想象一个 JSON 文档只有两个可能的属性:
persist
:布尔标志。默认为true
dbName
: 一个字符串。
当 persist
为 true
时,dbName
属性 必须 出现在文档中。当 persist
为 false
时,dbName
属性 必须 而不是 文档。
看起来很简单——这是我想出的模式:
{
"description": "Example",
"$id": "https://example.com/example",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"persist": {
"type": "boolean"
},
"dbName": {
"type": "string"
}
},
"additionalProperties": false,
"oneOf": [
{
"$comment": "persist attr is present and == false, dbName should not be present",
"properties": {
"persist": {
"enum": [
false
]
}
},
"not": {
"required": [
"dbName"
]
}
},
{
"$comment": "persist attr is present and == true, require dbName",
"properties": {
"persist": {
"enum": [
true
]
}
},
"required": [
"dbName"
]
},
{
"$comment": "persist attr is missing, its default value is true, require dbName",
"properties": {
"persist": false
},
"required": [
"dbName"
]
}
]
}
它几乎 有效。三个测试文件来练习三种可能的情况:
{ "persist": true, "dbName": "dn" }
--> 有效
{ "persist": false }
--> 有效
{ "dbName": "dn" }
--> 无效,错误如下:
[{
keyword: 'not',
dataPath: '',
schemaPath: '#/oneOf/0/not',
params: {},
message: 'should NOT be valid'
},
{
keyword: 'oneOf',
dataPath: '',
schemaPath: '#/oneOf',
params: {
passingSchemas: [Array]
},
message: 'should match exactly one schema in oneOf'
}
]
通过反复试验,很明显最后一个文档实际上匹配 oneOf
中的两个条件:oneOf/1
和 oneOf/2
。
我不知道为什么它会匹配 oneOf/1
,因为 json 文档中没有 persist
属性。我确定我遗漏了一些明显的东西,非常感谢任何帮助。
在您对 oneOf
子模式的评论中,您曾说过您希望模式验证 persist
属性是否存在,但它没有。
我们来看看为什么会这样……
Validation succeeds if, for each name that appears in both the
instance and as a name within this keyword's value, the child
instance for that name successfully validates against the
corresponding schema.
https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.5.4
这意味着,如果相应的键存在,值子模式将应用于对象中的实例值。如果没有,则不应用。
因此,如果您从 oneOf/1
和 oneOf/2
中减去 properties
,它们是等价的子模式。
你想要 oneOf/2
的是...
{
"$comment": "persist attr is present and == true, require dbName",
"properties": {
"persist": {
"const": true
}
},
"required": [
"persist",
"dbName"
]
}
这是一个演示:https://jsonschema.dev/s/cqMDM
您也需要对 oneOf/0
进行相同的更改。
如果您没有按要求指定persist
,子模式将不会检查键是否存在。