JSON 架构草案 v7 - 基于常见枚举类型选择的附加枚举属性的定义 - 在 XMLSpy Pro 2020 中测试
JSON Schema draft v7 - definition of additional enum properties based on common enum type selection - testing in XMLSpy Pro 2020
我正在尝试定义一个 json 模式,该模式对许多对象具有共同的枚举类型,然后根据选择的枚举,定义枚举的可能组合以及所需的其他元素.
该示例具有带 {IDNumber, Color, Furniture Type} 的家具数据,然后根据从枚举列表中选择的类型,获取分配有不同枚举的函数。我还放了一个 "Person assigned" 的例子作为一个额外的元素。
我认为我使用 anyof 和 const 正确地做到了这一点。但是,当我使用 XMLSpy Pro 2020 进行测试时,它会生成无效的 json 示例,而且当我尝试验证无效示例时,它也会通过……所以,1) 我表达得好吗? 2)我做错了什么? 3)有更好的方法吗? 4) 是工具还是 json 模式?
请帮忙。
JSON Schema :
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"FurnitureData": {
"type": "array",
"items": {
"type": "object",
"properties": {
"IDNumber": {
"type": "object",
"description": "Unique identifier",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"maxLength": 16
},
"readOnly": {
"type": "boolean",
"default": true
}
}
},
"Color": {
"type": "object",
"description": "Preferred color",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"default": "WOOD",
"enum": [
"BLUE",
"WOOD",
"GREEN"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
},
"Furniture Type": {
"type": "object",
"description": "Kind of Furniture",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"default": "CHAIR",
"enum": [
"LAMP",
"TABLE",
"CHAIR"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
}
},
"required": [
"IDNumber",
"Color",
"Furniture Type"
],
"anyOf": [
{
"properties": {
"Furniture Type": {
"value": {
"const": "LAMP"
}
},
"Function": {
"type": "object",
"description": "Lighting arrangement",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"LIGHT ON",
"LIGHT OFF"
]
}
}
}
},
"required": [
"Furniture Type",
"Function"
]
},
{
"properties": {
"Furniture Type": {
"value": {
"const": "TABLE"
}
},
"Function": {
"type": "object",
"description": "Size of table",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"3' x 4'",
"6' x 4'",
"12' x 4'",
"10' round"
]
}
}
}
},
"required": [
"Furniture Type",
"Function"
]
},
{
"properties": {
"Furniture Type": {
"value": {
"const": "CHAIR"
}
},
"Function": {
"type": "object",
"description": "Planned use",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"WORKSPACE SEAT",
"SPARE SEAT"
]
}
}
},
"Person assigned": {
"type": "object",
"description": "Seating assignment",
"required": [
"value"
],
"properties": {
"value": {
"type": "string"
}
}
}
},
"required": [
"Furniture Type",
"Function",
"Person assigned"
]
}
]
}
}
},
"required": [
"FurnitureData"
]
}
无效 JSON XMLSpy 验证为正常的示例:(它链接到信息页面中我的模式)
灯不应允许 6x4 作为功能...
{
"FurnitureData": [
{
"Color": {
"value": "WOOD",
"readOnly": "a",
"custom value": "a"
},
"IDNumber": {
"value": "a",
"readOnly": true
},
"Furniture Type": {
"value": "LAMP",
"custom value": "a"
},
"Function": {
"value": "6' x 4'",
"custom value": "a"
}
}
]
}
另一个无效示例...椅子有 "Person assigned" 并且显示了错误的类型值,但这也有效...
{
"FurnitureData": [
{
"Color": {
"value": "WOOD",
"readOnly": "a",
"custom value": "a"
},
"IDNumber": {
"value": "a",
"readOnly": true
},
"Furniture Type": {
"value": "CHAIR",
"custom value": "a"
},
"Function": {
"value": "6' x 4'",
"custom value": "a"
}
}
]
}
这是遵循中的建议
也许我必须使用 if-then 结构?在这里,我尝试在任何一个中使用 if-then,但我也得到了 json 的验证,它允许来自其他家具类型的枚举...
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"FurnitureData": {
"type": "array",
"items": {
"type": "object",
"properties": {
"IDNumber": {
"type": "object",
"description": "Unique identifier",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"maxLength": 16
},
"readOnly": {
"type": "boolean",
"default": true
}
}
},
"Color": {
"type": "object",
"description": "Preferred color",
"required": [
"value",
"readOnly"
],
"properties": {
"value": {
"type": "string",
"default": "WOOD",
"enum": [
"BLUE",
"WOOD",
"GREEN"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
},
"Furniture Type": {
"type": "object",
"description": "Kind of Furniture",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"default": "CHAIR",
"enum": [
"LAMP",
"TABLE",
"CHAIR"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
}
},
"required": [
"IDNumber",
"Color",
"Furniture Type"
],
"anyOf": [
{
"if": {
"properties": {
"Furniture Type": {
"value": {
"const": "LAMP"
}
}
}
},
"then": {
"properties": {
"Function": {
"type": "object",
"description": "Lighting arrangement",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"LIGHT ON",
"LIGHT OFF"
]
}
}
}
},
"required": [
"Function"
]
}
},
{
"if": {
"properties": {
"Furniture Type": {
"value": {
"const": "TABLE"
}
}
}
},
"then": {
"properties": {
"Function": {
"type": "object",
"description": "Size of table",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"3' x 4'",
"6' x 4'",
"12' x 4'",
"10' round"
]
}
}
}
},
"required": [
"Function"
]
}
},
{
"if": {
"properties": {
"Furniture Type": {
"value": {
"const": "CHAIR"
}
}
}
},
"then": {
"properties": {
"Function": {
"type": "object",
"description": "Planned use",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"WORKSPACE SEAT",
"SPARE SEAT"
]
}
}
},
"Person assigned": {
"type": "object",
"description": "Seating assignment",
"required": [
"value"
],
"properties": {
"value": {
"type": "string"
}
}
}
},
"required": [
"Function",
"Person assigned"
]
}
}
]
}
}
},
"required": [
"FurnitureData"
]
}
JSON 架构 properties
对象的值是子架构(JSON 架构本身)。
要知道,如果您在 properties.FurnitureData.anyOf[1].properties['Furniture Type']
处获取子模式并将其作为模式...它实际上不表达任何约束。
您架构中该位置的子架构是...
{
"value": {
"const": "TABLE"
}
}
而它需要...
{
"properties":{
"value": {
"const": "TABLE"
}
}
}
调试此类问题的最简单方法是测试您的假设。
您假设 allOf[1]
和 allOf[2]
应该失败,因此将这些子模式替换为 false
(布尔值是有效模式)。
这样做,你会发现假设是错误的,allOf[1]
是有效的。当然,您希望 const
被拾取,因此该子模式失败,但它没有被拾取,因为您缺少 properties
并且 value
不是有效的 JSON 架构关键字。
您可以 运行 使用 https://jsonschema.dev/s/Xt1Yi
进行此类快速测试
我正在尝试定义一个 json 模式,该模式对许多对象具有共同的枚举类型,然后根据选择的枚举,定义枚举的可能组合以及所需的其他元素. 该示例具有带 {IDNumber, Color, Furniture Type} 的家具数据,然后根据从枚举列表中选择的类型,获取分配有不同枚举的函数。我还放了一个 "Person assigned" 的例子作为一个额外的元素。
我认为我使用 anyof 和 const 正确地做到了这一点。但是,当我使用 XMLSpy Pro 2020 进行测试时,它会生成无效的 json 示例,而且当我尝试验证无效示例时,它也会通过……所以,1) 我表达得好吗? 2)我做错了什么? 3)有更好的方法吗? 4) 是工具还是 json 模式? 请帮忙。
JSON Schema :
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"FurnitureData": {
"type": "array",
"items": {
"type": "object",
"properties": {
"IDNumber": {
"type": "object",
"description": "Unique identifier",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"maxLength": 16
},
"readOnly": {
"type": "boolean",
"default": true
}
}
},
"Color": {
"type": "object",
"description": "Preferred color",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"default": "WOOD",
"enum": [
"BLUE",
"WOOD",
"GREEN"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
},
"Furniture Type": {
"type": "object",
"description": "Kind of Furniture",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"default": "CHAIR",
"enum": [
"LAMP",
"TABLE",
"CHAIR"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
}
},
"required": [
"IDNumber",
"Color",
"Furniture Type"
],
"anyOf": [
{
"properties": {
"Furniture Type": {
"value": {
"const": "LAMP"
}
},
"Function": {
"type": "object",
"description": "Lighting arrangement",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"LIGHT ON",
"LIGHT OFF"
]
}
}
}
},
"required": [
"Furniture Type",
"Function"
]
},
{
"properties": {
"Furniture Type": {
"value": {
"const": "TABLE"
}
},
"Function": {
"type": "object",
"description": "Size of table",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"3' x 4'",
"6' x 4'",
"12' x 4'",
"10' round"
]
}
}
}
},
"required": [
"Furniture Type",
"Function"
]
},
{
"properties": {
"Furniture Type": {
"value": {
"const": "CHAIR"
}
},
"Function": {
"type": "object",
"description": "Planned use",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"WORKSPACE SEAT",
"SPARE SEAT"
]
}
}
},
"Person assigned": {
"type": "object",
"description": "Seating assignment",
"required": [
"value"
],
"properties": {
"value": {
"type": "string"
}
}
}
},
"required": [
"Furniture Type",
"Function",
"Person assigned"
]
}
]
}
}
},
"required": [
"FurnitureData"
]
}
无效 JSON XMLSpy 验证为正常的示例:(它链接到信息页面中我的模式) 灯不应允许 6x4 作为功能...
{
"FurnitureData": [
{
"Color": {
"value": "WOOD",
"readOnly": "a",
"custom value": "a"
},
"IDNumber": {
"value": "a",
"readOnly": true
},
"Furniture Type": {
"value": "LAMP",
"custom value": "a"
},
"Function": {
"value": "6' x 4'",
"custom value": "a"
}
}
]
}
另一个无效示例...椅子有 "Person assigned" 并且显示了错误的类型值,但这也有效...
{
"FurnitureData": [
{
"Color": {
"value": "WOOD",
"readOnly": "a",
"custom value": "a"
},
"IDNumber": {
"value": "a",
"readOnly": true
},
"Furniture Type": {
"value": "CHAIR",
"custom value": "a"
},
"Function": {
"value": "6' x 4'",
"custom value": "a"
}
}
]
}
这是遵循中的建议
也许我必须使用 if-then 结构?在这里,我尝试在任何一个中使用 if-then,但我也得到了 json 的验证,它允许来自其他家具类型的枚举...
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"FurnitureData": {
"type": "array",
"items": {
"type": "object",
"properties": {
"IDNumber": {
"type": "object",
"description": "Unique identifier",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"maxLength": 16
},
"readOnly": {
"type": "boolean",
"default": true
}
}
},
"Color": {
"type": "object",
"description": "Preferred color",
"required": [
"value",
"readOnly"
],
"properties": {
"value": {
"type": "string",
"default": "WOOD",
"enum": [
"BLUE",
"WOOD",
"GREEN"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
},
"Furniture Type": {
"type": "object",
"description": "Kind of Furniture",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"default": "CHAIR",
"enum": [
"LAMP",
"TABLE",
"CHAIR"
]
},
"custom value": {
"type": "string",
"maxLength": 32
}
}
}
},
"required": [
"IDNumber",
"Color",
"Furniture Type"
],
"anyOf": [
{
"if": {
"properties": {
"Furniture Type": {
"value": {
"const": "LAMP"
}
}
}
},
"then": {
"properties": {
"Function": {
"type": "object",
"description": "Lighting arrangement",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"LIGHT ON",
"LIGHT OFF"
]
}
}
}
},
"required": [
"Function"
]
}
},
{
"if": {
"properties": {
"Furniture Type": {
"value": {
"const": "TABLE"
}
}
}
},
"then": {
"properties": {
"Function": {
"type": "object",
"description": "Size of table",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"3' x 4'",
"6' x 4'",
"12' x 4'",
"10' round"
]
}
}
}
},
"required": [
"Function"
]
}
},
{
"if": {
"properties": {
"Furniture Type": {
"value": {
"const": "CHAIR"
}
}
}
},
"then": {
"properties": {
"Function": {
"type": "object",
"description": "Planned use",
"required": [
"value"
],
"properties": {
"value": {
"type": "string",
"enum": [
"WORKSPACE SEAT",
"SPARE SEAT"
]
}
}
},
"Person assigned": {
"type": "object",
"description": "Seating assignment",
"required": [
"value"
],
"properties": {
"value": {
"type": "string"
}
}
}
},
"required": [
"Function",
"Person assigned"
]
}
}
]
}
}
},
"required": [
"FurnitureData"
]
}
JSON 架构 properties
对象的值是子架构(JSON 架构本身)。
要知道,如果您在 properties.FurnitureData.anyOf[1].properties['Furniture Type']
处获取子模式并将其作为模式...它实际上不表达任何约束。
您架构中该位置的子架构是...
{
"value": {
"const": "TABLE"
}
}
而它需要...
{
"properties":{
"value": {
"const": "TABLE"
}
}
}
调试此类问题的最简单方法是测试您的假设。
您假设 allOf[1]
和 allOf[2]
应该失败,因此将这些子模式替换为 false
(布尔值是有效模式)。
这样做,你会发现假设是错误的,allOf[1]
是有效的。当然,您希望 const
被拾取,因此该子模式失败,但它没有被拾取,因为您缺少 properties
并且 value
不是有效的 JSON 架构关键字。
您可以 运行 使用 https://jsonschema.dev/s/Xt1Yi
进行此类快速测试