根据先前的答案,我建立了一个方案,以满足我的要求。问题和答案可以看到这里。
由此产生的计划:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"virtual"
],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": [
"type",
"path",
"entity",
"nodes"
],
"properties": {
"type": {
"type": "string"
},
"path": {
"type": "string"
},
"entity": {
"enum": ["pde", "topaz"]
}
},
"anyOf": [
{
"properties": {
"entity": {"const": "pde"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"title": "The Items Schema",
"required": [
"id",
"type",
"address",
"nozzles"
],
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"address": {
"type": "integer"
},
"nozzles": {
"type": "array",
"items": {
"type": "integer"
}
}
}
}
}
}
},
{
"properties": {
"entity": {"const": "topaz"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"uid",
"utype",
"uaddress",
"unozzles"
],
"properties": {
"uid": {
"type": "integer"
},
"utype": {
"type": "string"
},
"uaddress": {
"type": "string"
},
"unozzles": {
"type": "boolean"
}
}
}
}
}
}
]
}
}
}
}和JSON:
{
"virtual": [
{
"type": "bus",
"path": "VBUS1",
"entity": "pde",
"nodes": [
{
"id": "vrt_1",
"type": "dispenser",
"address": 1,
"nozzles": [1, 2, 3]
},
{
"id": "vrt_2",
"type": "dispenser",
"address": 2,
"nozzles": [4, 5, 3]
}
]
},
{
"type": "bus",
"path": "VBUS2",
"entity": "topaz",
"nodes": [
{
"uid": 1,
"utype": "dispenser",
"uaddress": "false",
"unozzles": true
},
{
"uid": 2,
"utype": "dispenser",
"uaddress": "true",
"unozzles": false
}
]
}
]
}出现了以下问题。当type=bus有路径和实体字段时。但是,如果type=io缺少路径和实体字段,节点字段看起来与上述两个字段不同。
因此,我需要有跟踪类型字段值的anyOf和另一个适用于type=bus的anyOf。
我会尽量解释得更清楚。必须跟踪类型字段的值,如果它等于总线,则会出现路径和实体字段。根据实体的值,节点字段有一个特定的结构(正是上面的图表中所写的结构)。
我尝试用嵌套的anyOf创建一个模式:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"virtual"
],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": ["bus", "io"]
}
},
"anyOf": [
{
"properties": {
"type": {"const": "bus"},
"path": { "type": "string" },
"entity": { "enum": ["topaz", "pde"] }
},
"anyOf":[
{
"properties":{
"entity": {"const": "pde"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"type",
"address",
"nozzles"
],
"properties": {
"id": { "type": "string" },
"type": { "type": "string" },
"address": { "type": "integer" },
"nozzles": {
"type": "array",
"items": { "type": "integer" }
}
}
}
}
}
},
{
"entity": {"const": "topaz"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"uid",
"utype",
"uaddress",
"unozzles"
],
"properties": {
"uid": { "type": "integer" },
"utype": { "type": "string" },
"uaddress": { "type": "string" },
"unozzles": { "type": "boolean" }
}
}
}
}
]
},
{
"properties": {
"type": {"const": "io"},
"nodes": {
"type": "array",
"items":{
"type": "object",
"required": [
"num",
"key",
"title",
"path"
],
"properties": {
"num": { "type": "integer" },
"key": { "type": "integer" },
"title": { "type": "string" },
"path": { "type": "string" }
}
}
}
}
}
]
}
}
}
} 但一如预期,该计划甚至接受那些不应接受的计划。
无效架构的示例。对于type=bus,entity=pde,没有必需的id字段。对于type=bus,entity=topaz,没有强制的uid字段。感觉上第二个嵌套的anyOf被忽略了。
{
"virtual": [
{
"type": "bus",
"path": "VBUS1",
"entity": "pde",
"nodes": [
{
"not_id": "vrt_1",
"type": "dispenser",
"address": 1,
"nozzles": [
1,
2,
3
]
},
{
"id": "vrt_2",
"type": "dispenser",
"address": 2,
"nozzles": [
4,
5,
3
]
}
]
},
{
"type": "bus",
"path": "VBUS2",
"entity": "topaz",
"nodes": [
{
"not_uid": 1,
"utype": "dispenser",
"uaddress": "false",
"unozzles": true
},
{
"uid": 2,
"utype": "dispenser",
"uaddress": "true",
"unozzles": false
}
]
},
{
"type": "io",
"nodes": [
{
"num": 1,
"key": 123,
"title": "123",
"path": "123"
}
]
}
]
}在本例中,类型字段的anyOf按预期工作。我假设这个问题再次出现是因为方案布局错误,但是我在嵌套anyOf上找不到因特网上的信息。
当试图将所有检查插入到一个anyOf中时,一切都按预期工作。
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"virtual"
],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": { "enum": ["bus", "io"] }
},
"anyOf": [
{
"properties": {
"type": {"const": "bus"},
"path": { "type": "string" },
"entity": {"const": "pde"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"title": "The Items Schema",
"required": [
"id",
"type",
"address",
"nozzles"
],
"properties": {
"id": { "type": "string" },
"type": { "type": "string" },
"address": { "type": "integer" },
"nozzles": {
"type": "array",
"items": { "type": "integer" }
}
}
}
}
}
},
{
"properties": {
"type": {"const": "bus"},
"path": { "type": "string" },
"entity": {"const": "topaz"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"uid",
"utype",
"uaddress",
"unozzles"
],
"properties": {
"uid": { "type": "integer" },
"utype": { "type": "string" },
"uaddress": { "type": "string" },
"unozzles": { "type": "boolean" }
}
}
}
}
},
{
"properties": {
"type": {"const": "io"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"num",
"key",
"title",
"path"
],
"properties": {
"num": { "type": "integer" },
"key": { "type": "integer" },
"title": { "type": "string" },
"path": { "type": "string" }
}
}
}
}
}
]
}
}
}
}但是:
JSON模式本身,您希望为其创建一个模式:
{
"virtual": [
{
"type": "bus",
"path": "VBUS1",
"entity": "pde",
"nodes": [
{
"id": "vrt_1",
"type": "dispenser",
"address": 1,
"nozzles": [1, 2, 3]
},
{
"id": "vrt_2",
"type": "dispenser",
"address": 2,
"nozzles": [4, 5, 3]
}
]
},
{
"type": "bus",
"path": "VBUS2",
"entity": "topaz",
"nodes": [
{
"uid": 1,
"utype": "dispenser",
"uaddress": "false",
"unozzles": true
},
{
"uid": 2,
"utype": "dispenser",
"uaddress": "true",
"unozzles": false
}
]
},
{
"type": "io",
"nodes": [
"num": 4,
"key": 123456,
"title": "io",
"path": "default"
]
}
]
}完整的JSON有一个相当复杂的结构,这里只表示了它的一部分。因此,我想了解如何正确地构造这些东西(了解想法本身,最好能看到正确方案的例子)。至少是原理图)。
所以,总结一下。我需要了解如何在其中一个anyOf变体中实现任何一个。这可行吗?若然,我在哪里可以看到编制这类计划的例子和指示呢?如果没有,有什么解决办法吗?
发布于 2019-11-12 19:43:35
虽然嵌套anyOf在JSON中工作得很好,但我认为这不是最好的解决方案。扁平anyOf和使用一些definitions可以极大地清理模式,使其更易于推理。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["virtual"],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": ["type"],
"anyOf": [
{ "$ref": "#/definitions/pdm" },
{ "$ref": "#/definitions/topaz" },
{ "$ref": "#/definitions/io" }
]
}
}
},
"definitions": {
"pdm": {
"properties":{
"type": { "const": "bus" },
"entity": { "const": "pde" },
... type specific properties ...
}
},
"topaz": {
"properties": {
"type": { "const": "bus" },
"entity": { "const": "topaz" },
... type specific properties ...
}
},
"io": {
"properties": {
"type": { "const": "io" },
... type specific properties ...
}
}
}
}如果使用if/then/else或隐含模式而不是Enum模式,则可以获得更好的错误消息传递,但使用更复杂的模式。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["virtual"],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": ["type"],
"allOf": [
{ "$ref": "#/definitions/pdm" },
{ "$ref": "#/definitions/topaz" },
{ "$ref": "#/definitions/io" }
]
}
}
},
"definitions": {
"pdm": {
"if": {
"properties":{
"type": { "const": "bus" },
"entity": { "const": "pde" }
},
"required": ["type", "entity"]
},
"then": {
"properties": {
... type specific constraints ...
}
}
},
... additional types ...
}发布于 2019-11-12 06:40:34
我想我找到了解决办法。然而,如果有任何评论或更正-我将很高兴听到。
以防万一,我举了一个由此产生的计划的例子:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"virtual"
],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": ["bus", "io"]
}
},
"anyOf": [
{
"properties":{
"type": {"const": "bus"},
},
"anyOf":[
{
"properties":{
"path": { "type": "string" },
"entity": {"const": "pde"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"type",
"address",
"nozzles"
],
"properties": {
"id": { "type": "string" },
"type": { "type": "string" },
"address": { "type": "integer" },
"nozzles": {
"type": "array",
"items": { "type": "integer" }
}
}
}
}
}
},
{
"properties":{
"path": { "type": "string" },
"entity": {"const": "topaz"},
"nodes": {
"type": "array",
"items": {
"type": "object",
"required": [
"uid",
"utype",
"uaddress",
"unozzles"
],
"properties": {
"uid": { "type": "integer" },
"utype": { "type": "string" },
"uaddress": { "type": "string" },
"unozzles": { "type": "boolean" }
}
}
}
}
}
]
},
{
"properties": {
"type": {"const": "io"},
"nodes": {
"type": "array",
"items":{
"type": "object",
"required": [
"num",
"key",
"title",
"path"
],
"properties": {
"num": { "type": "integer" },
"key": { "type": "integer" },
"title": { "type": "string" },
"path": { "type": "string" }
}
}
}
}
}
]
}
}
}
} https://stackoverflow.com/questions/58796307
复制相似问题