JSON 架构 - 如何应用基于布尔值的条件并进一步限制 additionalProperties: false?
JSON Schema - How to apply conditionals based on boolean and further restrict with additionalProperties: false?
Ansible 获得了对 jsonschema 的支持,我有各种各样的用例,但大多数都需要条件。我一直在阅读 jsonschema 和 draft-7 if-then-else 的文档,并尝试了几种排列,但似乎只处理了我的目标的一半。希望有人能帮我铺平道路,为我提供一个我可以解构的实际例子。
基于“send_notifications”中的布尔值的两种可能性:
{
"capture_state": "value here",
"send_notifications": true,
"user_email_list": ["email@something.com", "email2@something.com"],
"host_info": [
{
"ansible_host": "192.20.xxx.xxx",
"ECRTicket": "1103035"
},
.... continued
]
}
或
{
"capture_state": "value here",
"send_notifications": false
}
本质上,仅允许并要求基于“send_notifications”中的布尔值的示例中显示的属性,如果这两种模式都不是,则无条件失败。我也可能会通过模式进一步改进这一点,但这些键和类型是一个很好的开始。
我最初生成了以下基本模式,用作操作和添加条件的参考,也许这个模式中的某些东西与使用条件和 additionalProperties:false 冲突,但对 jsonschema 来说是新手这对我来说不是很明显,所以寻求一些帮助,这样我就可以更频繁地使用它。任何帮助将不胜感激,感谢您的宝贵时间,刚开始在堆栈上发帖,如果我可以改进我的问题,请告诉我。
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"capture_state",
"send_notifications",
"user_email_list",
"host_info"
],
"properties": {
"capture_state": {
"type": "string"
},
"send_notifications": {
"type": "boolean"
},
"user_email_list": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
}
]
}
},
"host_info": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"ansible_host",
"ECRTicket"
],
"properties": {
"ansible_host": {
"type": "string"
},
"ECRTicket": {
"type": "string"
}
},
"additionalProperties": false
}
]
}
}
},
"additionalProperties": false
}
通常,每当您选择限制未知属性时,您都会遇到困难。我假设你有充分的理由,包括它是值得的。
有几种方法可以做到这一点。我以这种方式呈现它是因为当 JSON 实例未通过模式验证时它会产生最好的消息。
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"capture_state": { "type": "string" },
"send_notifications": { "type": "boolean" },
},
"required": ["capture_state", "send_notifications"],
"if": {
"properties": {
"send_notifications": { "const": true },
},
"required": ["send_notifications"]
},
"then": {
"properties": {
"capture_state": true,
"send_notifications": true,
"user_email_list": {
"type": "array",
"items": { "type": "string" }
},
"host_info": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ansible_host": { "type": "string" },
"ECRTicket": { "type": "string" }
},
"required": ["ansible_host", "ECRTicket"],
"additionalProperties": false
}
}
},
"required": ["user_email_list", "host_info"],
"additionalProperties": false
},
"else": {
"properties": {
"capture_state": true,
"send_notifications": true
},
"additionalProperties": false
}
}
additionalProperties
只识别在它出现的同一子模式中声明的属性。这意味着您需要包含一些虚拟 properties
条目,以便它知道在其他地方声明的属性架构。
我假设 ansible 不支持比 draft-07 更新的 JSON Schema 版本?如果是这样,您可以使用 unevaluatedProperties
而不是 additionalProperties
来避免跳过一些您必须使用 additionalProperties
.
的障碍
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"capture_state": { "type": "string" },
"send_notifications": { "type": "boolean" },
},
"required": ["capture_state", "send_notifications"],
"unevaluatedProperties": false,
"if": {
"properties": {
"send_notifications": { "const": true },
},
"required": ["send_notifications"]
},
"then": {
"properties": {
"user_email_list": {
"type": "array",
"items": { "type": "string" }
},
"host_info": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ansible_host": { "type": "string" },
"ECRTicket": { "type": "string" }
},
"required": ["ansible_host", "ECRTicket"],
"additionalProperties": false
}
}
},
"required": ["user_email_list", "host_info"]
}
}
如果 Ansible 的任何人碰巧看到这个,2020-12 草案包括 unevaluatedProperties
并将获得大量实施支持,因为它也包含在 OpenAPI 3.1 中。
Ansible 获得了对 jsonschema 的支持,我有各种各样的用例,但大多数都需要条件。我一直在阅读 jsonschema 和 draft-7 if-then-else 的文档,并尝试了几种排列,但似乎只处理了我的目标的一半。希望有人能帮我铺平道路,为我提供一个我可以解构的实际例子。
基于“send_notifications”中的布尔值的两种可能性:
{
"capture_state": "value here",
"send_notifications": true,
"user_email_list": ["email@something.com", "email2@something.com"],
"host_info": [
{
"ansible_host": "192.20.xxx.xxx",
"ECRTicket": "1103035"
},
.... continued
]
}
或
{
"capture_state": "value here",
"send_notifications": false
}
本质上,仅允许并要求基于“send_notifications”中的布尔值的示例中显示的属性,如果这两种模式都不是,则无条件失败。我也可能会通过模式进一步改进这一点,但这些键和类型是一个很好的开始。
我最初生成了以下基本模式,用作操作和添加条件的参考,也许这个模式中的某些东西与使用条件和 additionalProperties:false 冲突,但对 jsonschema 来说是新手这对我来说不是很明显,所以寻求一些帮助,这样我就可以更频繁地使用它。任何帮助将不胜感激,感谢您的宝贵时间,刚开始在堆栈上发帖,如果我可以改进我的问题,请告诉我。
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [
"capture_state",
"send_notifications",
"user_email_list",
"host_info"
],
"properties": {
"capture_state": {
"type": "string"
},
"send_notifications": {
"type": "boolean"
},
"user_email_list": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
}
]
}
},
"host_info": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"ansible_host",
"ECRTicket"
],
"properties": {
"ansible_host": {
"type": "string"
},
"ECRTicket": {
"type": "string"
}
},
"additionalProperties": false
}
]
}
}
},
"additionalProperties": false
}
通常,每当您选择限制未知属性时,您都会遇到困难。我假设你有充分的理由,包括它是值得的。
有几种方法可以做到这一点。我以这种方式呈现它是因为当 JSON 实例未通过模式验证时它会产生最好的消息。
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"capture_state": { "type": "string" },
"send_notifications": { "type": "boolean" },
},
"required": ["capture_state", "send_notifications"],
"if": {
"properties": {
"send_notifications": { "const": true },
},
"required": ["send_notifications"]
},
"then": {
"properties": {
"capture_state": true,
"send_notifications": true,
"user_email_list": {
"type": "array",
"items": { "type": "string" }
},
"host_info": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ansible_host": { "type": "string" },
"ECRTicket": { "type": "string" }
},
"required": ["ansible_host", "ECRTicket"],
"additionalProperties": false
}
}
},
"required": ["user_email_list", "host_info"],
"additionalProperties": false
},
"else": {
"properties": {
"capture_state": true,
"send_notifications": true
},
"additionalProperties": false
}
}
additionalProperties
只识别在它出现的同一子模式中声明的属性。这意味着您需要包含一些虚拟 properties
条目,以便它知道在其他地方声明的属性架构。
我假设 ansible 不支持比 draft-07 更新的 JSON Schema 版本?如果是这样,您可以使用 unevaluatedProperties
而不是 additionalProperties
来避免跳过一些您必须使用 additionalProperties
.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"capture_state": { "type": "string" },
"send_notifications": { "type": "boolean" },
},
"required": ["capture_state", "send_notifications"],
"unevaluatedProperties": false,
"if": {
"properties": {
"send_notifications": { "const": true },
},
"required": ["send_notifications"]
},
"then": {
"properties": {
"user_email_list": {
"type": "array",
"items": { "type": "string" }
},
"host_info": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ansible_host": { "type": "string" },
"ECRTicket": { "type": "string" }
},
"required": ["ansible_host", "ECRTicket"],
"additionalProperties": false
}
}
},
"required": ["user_email_list", "host_info"]
}
}
如果 Ansible 的任何人碰巧看到这个,2020-12 草案包括 unevaluatedProperties
并将获得大量实施支持,因为它也包含在 OpenAPI 3.1 中。