我是json模式验证的新手,我无法根据json中更深的字段的存在和值来验证必填字段
下面是我当前的模式和一个示例json。 我需要说如果“ SW Large”存在且值为真,那么它要求Register对象内存在更高的“ SW Words”
我在下面的架构中拥有的“ anyOf”是我的尝试。
可以说“ SW Large”为真,则不需要“ SW Words”,但是如果不存在“ SW Large”字段,它仍会坚持要求“ SW Words”。
如何更改“ anyOf”和“ allOf”以检查“ SW Large”是否确实存在?
编辑:剥离json使其更易于管理
模式:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"additionalProperties": false,
"required": [
"Registers"
],
"properties": {
"Registers": {
"$id": "#/properties/Registers",
"type": "array",
"items": {
"$id": "#/properties/Registers/items",
"type": "object",
"additionalProperties": false,
"required": [
"Name",
"Address",
"Fields"
],
"anyOf": [
{
"allOf": [
{ "not": { "properties": { "Fields" : { "items": { "properties": { "SW Large": { "const": true } } } } } } }
]
},
{
"required": ["SW Words"]
}
],
"properties": {
"Name": {
"$id": "#/properties/Registers/items/properties/Name",
"type": "string"
},
"Address": {
"$id": "#/properties/Registers/items/properties/Address",
"type": "string"
},
"SW Words": {
"$id": "#/properties/Sections/items/properties/Blocks/items/properties/SW Words",
"type": "integer",
"default": 2,
"minimum": 2
},
"Fields": {
"$id": "#/properties/properties/Registers/items/properties/Fields",
"type": "array",
"items": {
"$id": "#/properties/Registers/items/properties/Fields/items",
"type": "object",
"additionalProperties": false,
"required": [
"Name"
],
"properties": {
"Name": {
"$id": "#/properties/Registers/items/properties/Fields/items/properties/Name",
"type": "string"
},
"SW Large": {
"$id": "#/properties/Registers/items/properties/Fields/items/properties/SW Large",
"type": "boolean"
}
}
}
}
}
}
}
}
}
Json示例
{
"Registers": [
{
"Name": "device",
"Address": "100",
"SW Words": 2,
"Fields": [
{
"Name" : "Product",
"SW Large" : true
},
{
"Name": "Version"
}
]
}
]
}
答案 0 :(得分:0)
Y,向上的依赖关系确实令人不快。模型必须采用这种方式成形吗?
您处在正确的轨道上。您缺少的是正确检查“字段”数组中的至少一个元素是否具有“ SW Large”:true ,然后确定适当的依赖关系。
自草案06起,使用“包含”关键字解决。为了不重复内容,建议阅读以下内容:
Json Schema: Require a property only when a specific property is present in a deep nested object(非常有教育意义!)
https://json-schema.org/understanding-json-schema/reference/array.html
您的架构在下面进行了重新设计。 参见“定义”部分
首先,它在“字段” 定义中添加“ contains”:{ schema }。为了将其用作逻辑含义中的条件,我需要将其作为单独的架构。
"definitions" : {
"Fields-contains-at-least-1-element-with-SW-Large-true" : {
"properties": {
"Fields" : {
"contains" : {
"properties": {
"SW Large": { "enum": [true] }
},
"required" : ["SW Large"]
}
}
},
}
},
如果您要永久添加它,它可能看起来像:
"Fields" : {
"type" : "array",
"contains" : {
"properties": {
"SW Large": { "enum": [true] }
},
"required" : ["SW Large"]
}
"items": {...},
}
转换为“ “字段” 数组的至少一项的必须包含具有所述属性名称和所述值的对象”。每个带有“ Fields” 数组的JSON,其中不包含带有“ SW Large”:true 的项目,将无法通过这种模式验证。如果您将“包含” 模式定义反转,例如:
"Fields" : {
"type" : "array",
"contains" : {
"not" : {
"properties": {
"SW Large": { "enum": [true] }
},
"required" : ["SW Large"]
}
}
"items": {...},
}
它将转换为“ “字段” 数组中的任何项目都不能包含具有所述属性名称和所述值的对象”。每个具有“ Fields” 数组的JSON至少包含一个带有“ SW Large”:true 的项目,将无法通过这种模式进行验证。
我不希望以上任何事情发生。我想将“字段/包含” 条件与需要或不需要上一层“ SW Words” 属性的链接,因此将架构排除在“定义”部分之外,正确使用它。
“向上依赖” 是使用该检查和带有“ anyOf”关键字的适当逻辑含义定义的
它至少包含1个带有“ SW Large”(SW大)的项目:true或“ SW Words”为必填项
"definitions" : {
"upward-dependency" : {
"anyOf" : [
{ "not" : {"$ref" : "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true"} },
{ "required" : ["SW Words"] }
]
},
},
在“寄存器”数组的单个项目级别,我添加了“依赖项”。只要“字段”项出现在“注册”项之一中,就会检查它是否包含不幸的“ SW Large”:true ,如果包含,则需要使用“ SW Words”。瞧!
"items" : {
"$id": "#/properties/Registers/items
"type" : "object",
"properties" : {
"Fields": {
"$id": "#/properties/Registers/items/properties/Fields",
"type": "array",
"items": {
"$id": "#/properties/Registers/items/properties/Fields/items",
"type": "object",
"propertyNames" : {
"enum" : [
"Name",
"SW Large"
]
},
"required": [
"Name"
],
"properties": {
"Name": {
"$id": "#/properties/Registers/items/properties/Fields/items/properties/Name",
"type": "string"
},
"SW Large": {
"$id": "#/properties/Registers/items/properties/Fields/items/properties/SW Large",
"type": "boolean"
}
}
}
}
},
"dependencies" : {
"Fields" : { "$ref" : "#/definitions/upward-dependency" }
},
}
我已经使用在线验证器检查了架构,并将您的对象添加到“示例”部分。
完整架构:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"propertyNames" : {
"enum" : [
"Registers"
]
},
"required": [
"Registers"
],
"examples" : [
{
"Registers": [
{
"Name": "device",
"Address": "100",
"SW Words": 2,
"Fields": [
{
"Name" : "Product",
"SW Large" : true
},
{
"Name": "Version"
}
]
}
]
}
],
"properties": {
"Registers": {
"$id": "#/properties/Registers",
"type": "array",
"items": {
"$id": "#/properties/Registers/items",
"type": "object",
"propertyNames" : {
"enum" : [
"Name",
"Address",
"SW Words",
"Fields"
]
},
"required": [
"Name",
"Address",
"Fields"
],
"properties": {
"Name": {
"$id": "#/properties/Registers/items/properties/Name",
"type": "string"
},
"Address": {
"$id": "#/properties/Registers/items/properties/Address",
"type": "string"
},
"SW Words": {
"$id": "#/properties/Sections/items/properties/Blocks/items/properties/SW Words",
"type": "integer",
"default": 2,
"minimum": 2
},
"Fields": {
"$id": "#/properties/Registers/items/properties/Fields",
"type": "array",
"items": {
"$id": "#/properties/Registers/items/properties/Fields/items",
"type": "object",
"propertyNames" : {
"enum" : [
"Name",
"SW Large"
]
},
"required": [
"Name"
],
"properties": {
"Name": {
"type": "string"
},
"SW Large": {
"type": "boolean"
}
}
}
}
},
"dependencies" : {
"Fields" : { "$ref" : "#/definitions/upward-dependency" }
},
}
}
},
"definitions" : {
"upward-dependency" : {
"anyOf" : [
{ "not" : {"$ref" : "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true"} },
{ "required" : ["SW Words"] }
]
},
"Fields-contains-at-least-1-element-with-SW-Large-true" : {
"properties": {
"Fields" : {
"contains" : {
"properties": {
"SW Large": { "enum": [true] }
},
"required" : ["SW Large"]
}
}
},
}
},
}
请使用“ propertyNames”代替“ additionalProperties”:false 。专门介绍该属性是为了确保在JSON对象验证的aginst模式中仅存在所需的属性。
"propertyNames" : {
"enum" : [
"Registers"
]
}
请参阅:https://json-schema.org/understanding-json-schema/reference/object.html#property-names
非常重要的一点是,应根据应在哪个级别上应用方案/子方案来正确调整方案/子方案的形状。请注意“#/ definitions / Fields-contains-at-least-1-element-with-SW-Large-true” 如何正确反映“#/ Registers / items” < / em>嵌套级别(因为“依赖项”应用于“#/ Registers / items” 级别的对象,因此可以将其视为“” ## / Registers / items / dependencies” )。请参见https://json-schema.org/understanding-json-schema/reference/object.html#dependencies。
如果您打算分别验证“字段” 数组的单个项,或者甚至分别验证“ Registers” 数组的单个项,则可以考虑重塑架构以分隔单独的子项类似于我在这里https://stackoverflow.com/a/53309856/2811843中对“ questionA” 所做的处理。因此,如果有必要,您可以轻松地从主架构中排除子架构,并使用“ $ ref” 关键字正确引用它们。对JSON指针和相对JSON指针的一些阅读对于构造复杂模式也可能有用。
值得开始的地方:https://json-schema.org/understanding-json-schema/structuring.html
我希望它能帮上忙。