На основании предыдущего ответа я построил схему, которая отвечала бы моим требованиям. Вопрос и ответ на него можно увидеть здесь .
Полученная схема:
{
"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
}
]
}
]
}
появилась следующая проблема. Когда тип = шина, JSON имеет поля пути и сущности. Но, если type = io, поля пути и сущности отсутствуют, а поле узла выглядит не так, как в предыдущих двух.
Следовательно, мне нужно иметь anyOf, который бы отслеживал значение поля типа, и другое anyOf, которое быработа для type = bus.
Я постараюсь объяснить более четко. Необходимо отслеживать значение поля типа и, если оно равно bus, то появляются поля пути и сущности. В зависимости от значения объекта поле узла имеет определенную структуру (в точности то, что написано на диаграмме выше).
Я пытался создать схему с вложенным 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. Не существует обязательного поля uid для type = bus, entity = topaz. Такое ощущение, что второе вложенное 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"
}
]
}
]
}
Проверьте правильность неверного JSON .
В этом случае 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. Это возможно? И, если да, где я могу увидеть примеры и инструкции по составлению таких схем? Если нет, есть ли обходной путь?