JSON 架构:验证自定义 $ref'd 对象数组
JSON Schema: validating an array of custom $ref'd objects
背景:嗨!我一直在尝试使用一种模式来验证对象内的数组是否包含 仅 我的 definitions
块内定义的一些对象。
例如,我要验证以下 JSON 数据:
{
"component_type":"section",
"component_properties":{
"section_name":"first_section",
"fields":[
{
"component_type":"spacer",
"component_properties":{
"width":6
}
},
{
"component_type":"textbox",
"component_properties":{
"display_text":"hello!",
"text_color":"black"
}
},
{
"component_type":"spacer",
"component_properties":{
"width":3
}
}
]
}
}
此数据背后的想法是,在最高级别定义了一个 section
"component",填充了定义为要验证的子组件(spacer
, textbox
).
我的主要问题: 我不太明白如何验证仅由几个定义的对象组成的数组。我当前的架构如下:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"component_type": {
"type": "string",
"const": "section"
},
"component_properties": {
"type": "object",
"properties": {
"section_name": { "type": "string"},
"sections": {
"type": "array",
"oneOf": [
{ "$ref": "#/definitions/section_field" },
{
"type": "array",
"items": {
"$ref": "#/definitions/section_field"
}
}
]
}
}
}
},
"definitions": {
"spacer": {
"type": "object",
"properties": {
"component_type": {
"type": "string",
"const": "spacer"
},
"component_properties": {
"width": "number"
}
}
},
"textbox": {
"type": "object",
"properties": {
"component_type": {
"type": "string",
"const": "textbox"
},
"component_properties": {
"display_text": "hello!",
"text_color": "purple"
}
}
},
"section_field": {
"oneOf": [
{
"$ref": "#/definitions/spacer"
},
{
"$ref": "#/definitions/textbox"
}
]
}
}
}
此架构无法确保 component_properties 的 "fields" 数组内的所有项目在节级别都具有字段 "component_type": "spacer"
或 "component_type": "textbox"
。例如,"component_type": "another_one"
应该无法通过验证。
如果有任何其他信息对您有帮助,请随时告诉我!如果能提供一些指导,我将不胜感激。
你的架构几乎没问题——除了以下细节:
sections
属性里面的”type”: “array”
应该去掉。只有 ”oneOf”
应该保留。否则第一个 "oneOf"
部分(单个元素)将永远无效。
"component_properties"
应该属于 "type": "object"
本身,然后在其 "properties"
中列出 width
/display_text
/text_color
。看起来,您只是复制了示例内容。
但是,由于拼写错误,您的架构接受了您的示例:
- 在您的示例中,您有一个
fields
属性。但在您的架构中,它被称为 sections
。我假设它应该在两者中都被称为 fields
。
由于 none 个属性被标记为 required
,因此给定的示例可以正常验证。 fields
属性 没有限制。
如果您将 sections
标记为 required
,它会抱怨。
总而言之,您的架构的以下版本应该可以满足您的要求:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": ["component_type", "component_properties"],
"properties": {
"component_type": { "const": "section" },
"component_properties": {
"type": "object",
"required": ["section_name", "fields"],
"properties": {
"section_name": { "type": "string" },
"fields": {
"oneOf": [
{ "$ref": "#/definitions/section_field" },
{
"type": "array",
"items": { "$ref": "#/definitions/section_field" }
}
]
}
}
}
},
"definitions": {
"spacer": {
"type": "object",
"required": ["component_type", "component_properties"],
"properties": {
"component_type": { "const": "spacer" },
"component_properties": {
"properties": {
"width": { "type": "number" }
}
}
}
},
"textbox": {
"type": "object",
"required": ["component_type", "component_properties"],
"properties": {
"component_type": { "const": "textbox" },
"component_properties": {
"type": "object",
"properties": {
"display_text": { "type": "string" },
"text_color": { "type": "string" }
}
}
}
},
"section_field": {
"oneOf": [
{ "$ref": "#/definitions/spacer" },
{ "$ref": "#/definitions/textbox" }
]
}
}
}
背景:嗨!我一直在尝试使用一种模式来验证对象内的数组是否包含 仅 我的 definitions
块内定义的一些对象。
例如,我要验证以下 JSON 数据:
{
"component_type":"section",
"component_properties":{
"section_name":"first_section",
"fields":[
{
"component_type":"spacer",
"component_properties":{
"width":6
}
},
{
"component_type":"textbox",
"component_properties":{
"display_text":"hello!",
"text_color":"black"
}
},
{
"component_type":"spacer",
"component_properties":{
"width":3
}
}
]
}
}
此数据背后的想法是,在最高级别定义了一个 section
"component",填充了定义为要验证的子组件(spacer
, textbox
).
我的主要问题: 我不太明白如何验证仅由几个定义的对象组成的数组。我当前的架构如下:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"component_type": {
"type": "string",
"const": "section"
},
"component_properties": {
"type": "object",
"properties": {
"section_name": { "type": "string"},
"sections": {
"type": "array",
"oneOf": [
{ "$ref": "#/definitions/section_field" },
{
"type": "array",
"items": {
"$ref": "#/definitions/section_field"
}
}
]
}
}
}
},
"definitions": {
"spacer": {
"type": "object",
"properties": {
"component_type": {
"type": "string",
"const": "spacer"
},
"component_properties": {
"width": "number"
}
}
},
"textbox": {
"type": "object",
"properties": {
"component_type": {
"type": "string",
"const": "textbox"
},
"component_properties": {
"display_text": "hello!",
"text_color": "purple"
}
}
},
"section_field": {
"oneOf": [
{
"$ref": "#/definitions/spacer"
},
{
"$ref": "#/definitions/textbox"
}
]
}
}
}
此架构无法确保 component_properties 的 "fields" 数组内的所有项目在节级别都具有字段 "component_type": "spacer"
或 "component_type": "textbox"
。例如,"component_type": "another_one"
应该无法通过验证。
如果有任何其他信息对您有帮助,请随时告诉我!如果能提供一些指导,我将不胜感激。
你的架构几乎没问题——除了以下细节:
sections
属性里面的”type”: “array”
应该去掉。只有”oneOf”
应该保留。否则第一个"oneOf"
部分(单个元素)将永远无效。"component_properties"
应该属于"type": "object"
本身,然后在其"properties"
中列出width
/display_text
/text_color
。看起来,您只是复制了示例内容。
但是,由于拼写错误,您的架构接受了您的示例:
- 在您的示例中,您有一个
fields
属性。但在您的架构中,它被称为sections
。我假设它应该在两者中都被称为fields
。
由于 none 个属性被标记为 required
,因此给定的示例可以正常验证。 fields
属性 没有限制。
如果您将 sections
标记为 required
,它会抱怨。
总而言之,您的架构的以下版本应该可以满足您的要求:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": ["component_type", "component_properties"],
"properties": {
"component_type": { "const": "section" },
"component_properties": {
"type": "object",
"required": ["section_name", "fields"],
"properties": {
"section_name": { "type": "string" },
"fields": {
"oneOf": [
{ "$ref": "#/definitions/section_field" },
{
"type": "array",
"items": { "$ref": "#/definitions/section_field" }
}
]
}
}
}
},
"definitions": {
"spacer": {
"type": "object",
"required": ["component_type", "component_properties"],
"properties": {
"component_type": { "const": "spacer" },
"component_properties": {
"properties": {
"width": { "type": "number" }
}
}
}
},
"textbox": {
"type": "object",
"required": ["component_type", "component_properties"],
"properties": {
"component_type": { "const": "textbox" },
"component_properties": {
"type": "object",
"properties": {
"display_text": { "type": "string" },
"text_color": { "type": "string" }
}
}
}
},
"section_field": {
"oneOf": [
{ "$ref": "#/definitions/spacer" },
{ "$ref": "#/definitions/textbox" }
]
}
}
}