JSON 模式 - 即使 "if" 不正确,if then 语句也总是被评估
JSON Schema - if then statement is always evaluated even when "if" isn't true
我有一个 JSON 架构,在架构中 - 当 属性 type
等于 menu
时,那么 属性 default
应该是一个整数或一个名为“default”的字符串。问题是,即使 type
不是“菜单”。
(JSON 中有名为“type”和“default”的属性,不要与 JSON 架构类型和默认键混淆。
Schema 缩减为相关属性:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"title": "HubSpot Module",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of field, see [field types](https://developers.hubspot.com/en/docs/cms/building-blocks/module-theme-fields#field-types) for documentation on all field types."
},
"default": {
"type": ["string", "integer", "array", "boolean", "null", "number", "object"],
"description": "Default value for the field.",
"if": {
"properties": {
"type": {
"const": "menu"
}
}
},
"then": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string",
"enum": [
"default"
]
}
],
"description": "The menu ID for the menu. The default value of null, defaults to the default menu under navigation.",
"default": "null"
},
"else": {
"anyOf": [
{
"type": ["string", "integer", "array", "boolean", "null", "number", "object"]
}
]
}
}
},
"required": [
"name",
"label",
"type"
]
}
}
当满足这些条件时它会起作用,例如
[
{
"label": "Primary menu field",
"name": "primary_menu_field",
"type": "menu",
"default": 123
}
]
[
{
"label": "Primary menu field",
"name": "primary_menu_field",
"type": "menu",
"default": "default"
}
]
这些都没有抛出警告。但是以下抛出警告:Incorrect type. Expected "integer".
[
{
"name": "boolean_field",
"label": "Boolean field",
"required": false,
"locked": false,
"type": "boolean",
"inline_help_text": "",
"help_text": "",
"default": false
}
]
尽管 type
属性 没有被命名为“菜单”。将鼠标悬停在“默认”属性 VSCode 上确实给出了我对它的定义。
似乎 if
语句总是被评估为 true - 只有当 属性 type
的值为 menu
时才应该评估它,是有什么我想念的吗?
您的 if
没有按预期工作,因为它在错误的位置并且没有受到足够的约束。您在“默认”属性 模式中有 if
,这意味着 if
模式将应用于“默认”属性 的值。所以,如果“默认”是 123
,那么 if
模式,
{
"properties": {
"type": { "const": "menu" }
}
}
将根据 123
进行评估。由于 123
是一个数字,properties
关键字将被忽略,架构将通过验证并应用 then
架构。这就是我所说的 if
受到约束的意思。使用 if
时,您需要检查丢失的数据或错误类型的数据。
{
"type": "object",
"properties": {
"type": { "const": "menu" }
},
"required": ["type"]
}
现在,您将在根据此模式验证 123
时收到一条错误消息,并希望能找出您的 if
/then
位置错误。 if
需要应用于对象,您需要将其向上移动到架构中的该级别。这将使您的 if
得到预期的评估。不要忘记更新 then
,因为您移动了架构。我还需要在对象级别而不是 属性 级别进行定义。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string" }
},
"required": ["name", "label", "type"],
"if": {
"type": "object",
"properties": {
"type": { "const": "menu" }
},
"required": ["type"]
},
"then": {
"properties": {
"default": {
"anyOf": [
{ "type": "integer" },
{ "const": "default" }
]
}
}
}
}
}
你的if
/then
/else
在default
属性下面,所以它在default
下面找对象,而不是在你想要的地方上一层。
此外,如果 属性 实际上不存在,if
条件中的 properties
检查将始终为真,因此要确保它确实存在,您可以添加一个 "required": <propertyname>
旁边。
(正交地,您的 type
检查并没有真正做任何事情,因为您在列表中包含了所有有效类型。您最好将其省略以指示“这可以是任何类型”。)
我有一个 JSON 架构,在架构中 - 当 属性 type
等于 menu
时,那么 属性 default
应该是一个整数或一个名为“default”的字符串。问题是,即使 type
不是“菜单”。
(JSON 中有名为“type”和“default”的属性,不要与 JSON 架构类型和默认键混淆。
Schema 缩减为相关属性:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"title": "HubSpot Module",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of field, see [field types](https://developers.hubspot.com/en/docs/cms/building-blocks/module-theme-fields#field-types) for documentation on all field types."
},
"default": {
"type": ["string", "integer", "array", "boolean", "null", "number", "object"],
"description": "Default value for the field.",
"if": {
"properties": {
"type": {
"const": "menu"
}
}
},
"then": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string",
"enum": [
"default"
]
}
],
"description": "The menu ID for the menu. The default value of null, defaults to the default menu under navigation.",
"default": "null"
},
"else": {
"anyOf": [
{
"type": ["string", "integer", "array", "boolean", "null", "number", "object"]
}
]
}
}
},
"required": [
"name",
"label",
"type"
]
}
}
当满足这些条件时它会起作用,例如
[
{
"label": "Primary menu field",
"name": "primary_menu_field",
"type": "menu",
"default": 123
}
]
[
{
"label": "Primary menu field",
"name": "primary_menu_field",
"type": "menu",
"default": "default"
}
]
这些都没有抛出警告。但是以下抛出警告:Incorrect type. Expected "integer".
[
{
"name": "boolean_field",
"label": "Boolean field",
"required": false,
"locked": false,
"type": "boolean",
"inline_help_text": "",
"help_text": "",
"default": false
}
]
尽管 type
属性 没有被命名为“菜单”。将鼠标悬停在“默认”属性 VSCode 上确实给出了我对它的定义。
似乎 if
语句总是被评估为 true - 只有当 属性 type
的值为 menu
时才应该评估它,是有什么我想念的吗?
您的 if
没有按预期工作,因为它在错误的位置并且没有受到足够的约束。您在“默认”属性 模式中有 if
,这意味着 if
模式将应用于“默认”属性 的值。所以,如果“默认”是 123
,那么 if
模式,
{
"properties": {
"type": { "const": "menu" }
}
}
将根据 123
进行评估。由于 123
是一个数字,properties
关键字将被忽略,架构将通过验证并应用 then
架构。这就是我所说的 if
受到约束的意思。使用 if
时,您需要检查丢失的数据或错误类型的数据。
{
"type": "object",
"properties": {
"type": { "const": "menu" }
},
"required": ["type"]
}
现在,您将在根据此模式验证 123
时收到一条错误消息,并希望能找出您的 if
/then
位置错误。 if
需要应用于对象,您需要将其向上移动到架构中的该级别。这将使您的 if
得到预期的评估。不要忘记更新 then
,因为您移动了架构。我还需要在对象级别而不是 属性 级别进行定义。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string" }
},
"required": ["name", "label", "type"],
"if": {
"type": "object",
"properties": {
"type": { "const": "menu" }
},
"required": ["type"]
},
"then": {
"properties": {
"default": {
"anyOf": [
{ "type": "integer" },
{ "const": "default" }
]
}
}
}
}
}
你的if
/then
/else
在default
属性下面,所以它在default
下面找对象,而不是在你想要的地方上一层。
此外,如果 属性 实际上不存在,if
条件中的 properties
检查将始终为真,因此要确保它确实存在,您可以添加一个 "required": <propertyname>
旁边。
(正交地,您的 type
检查并没有真正做任何事情,因为您在列表中包含了所有有效类型。您最好将其省略以指示“这可以是任何类型”。)