Проверка схемы Json на основе значения, указанного для свойства - PullRequest
1 голос
/ 18 июня 2019

У меня есть запрос Json, имеющий указанные ниже данные и соответствующую ему схему json

С помощью этого запроса я хочу заполнить несколько полей в зависимости от режима

Скажите, если mode равно 1, тогда я хочу, чтобы поля a и b в obj1 были обязательными, а поле x в obj3 - обязательным. Теперь, если режим равен 2, я бы хотел, чтобы поля p, q и r в obj2 были обязательными, поля a и c в obj1, как требуется, и поле y в obj3, как требуется. Далее, если режим 3, я хочу только поля a и c, как требуется

JSON запрос

{
  "mode": "1",
  "obj1": {
      "a": 12,
      "b": "test",
      "c": "18 June 2019"
      },
 "obj2": {
      "p": 100,
      "q": "new",
      "r": "19 June 2019",
      "s" : "test2"
      },
  "obj3": {
      "x": 12,
      "y": "test3"
      }
}


**Json schema**
{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "properties": {
    "mode": {
      "$id": "#/properties/mode",
      "type": "string",
      "examples": [
        "1"
      ]
    },
    "obj1": {
      "$id": "#/properties/obj1",
      "type": "object",
      "title": "The Obj 1 Schema",
      "properties": {
        "a": {
          "$id": "#/properties/obj1/properties/a",
          "type": "integer",
          "examples": [
            12
          ]
        },
        "b": {
          "$id": "#/properties/obj1/properties/b",
          "type": "string",
          "examples": [
            "test"
          ]
        },
        "c": {
          "$id": "#/properties/obj1/properties/c",
          "type": "string",
          "examples": [
            "18 June 2019"
          ]
        }
      }
    },
    "obj 2": {
      "$id": "#/properties/obj2",
      "type": "object",
      "title": "The Obj 2 Schema",
      "properties": {
        "p": {
          "$id": "#/properties/obj2/properties/p",
          "type": "integer",
          "examples": [
            100
          ]
        },
        "q": {
          "$id": "#/properties/obj2/properties/q",
          "type": "string",
          "examples": [
            "new"
          ]
        },
        "r": {
          "$id": "#/properties/obj2/properties/r",
          "type": "string",
          "examples": [
            "19 June 2019"
          ]
        },
        "s": {
          "$id": "#/properties/obj2/properties/s",
          "type": "string",
          "examples": [
            "test2"
          ]
        }
      }
    },
    "obj 3": {
      "$id": "#/properties/obj3",
      "type": "object",
      "title": "The Obj 3 Schema",
      "properties": {
        "x": {
          "$id": "#/properties/obj3/properties/x",
          "type": "integer",
          "examples": [
            12
          ]
        },
        "y": {
          "$id": "#/properties/obj3/properties/y",
          "type": "string",
          "examples": [
            "test3"
          ]
        }
      }
    }
  }
}

РЕДАКТИРОВАТЬ - Изменена схема для проверки на основе предложения @ gregsdennis

JSON SCHEMA

    {
      "definitions": {},
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$id": "http://example.com/root.json",
      "type": "object",
      "properties": {
        "mode": {
          "$id": "#/properties/mode",
          "type": "string",
          "examples": [
            "1"
          ]
        },
        "obj1": {
          "$id": "#/properties/obj1",
          "type": "object",
          "title": "The Obj 1 Schema",
          "properties": {
            "a": {
              "type": "integer",
              "examples": [
                12
              ]
            },
            "b": {
              "type": "string",
              "examples": [
                "test"
              ]
            },
            "c": {
              "type": "string",
              "examples": [
                "18 June 2019"
              ]
            }
          }
        },
        "obj 2": {
          "$id": "#/properties/obj2",
          "type": "object",
          "title": "The Obj 2 Schema",
          "properties": {
            "p": {
              "type": "integer",
              "examples": [
                100
              ]
            },
            "q": {
              "type": "string",
              "examples": [
                "new"
              ]
            },
            "r": {
              "type": "string",
              "examples": [
                "19 June 2019"
              ]
            },
            "s": {
              "type": "string",
              "examples": [
                "test2"
              ]
            }
          }
        },
        "obj 3": {
          "$id": "#/properties/obj3",
          "type": "object",
          "title": "The Obj 3 Schema",
          "properties": {
            "x": {
              "type": "integer",
              "examples": [
                12
              ]
            },
            "y": {
              "type": "string",
              "examples": [
                "test3"
              ]
            }
          }
        }
      },
"oneOf": [
    {
      "properties": {
        "mode": {"const": 1},
        "obj1": {"required": ["a","b"]},
        "obj3": {"required": ["x"]}
       }
    },
    {
      "properties": {
        "mode": {"const": 2},
        "obj2": {"required": ["p","q","r"]},
        "obj1": {"required": ["a","c"]},
        "obj3": {"required": ["y"]}
       }
    }
]
    }

Итак, вкратце, независимо от того, сколько у меня режимов, полей или объектов, я бы хотел, чтобы в определенный момент времени для определенного режима требовалось только несколько выбранных полей из разных объектов. Может ли кто-нибудь предложить какие-либо решения для достижения этой цели? Возможно ли иметь такие проверки в схеме json?

1 Ответ

1 голос
/ 19 июня 2019

То, что вы хотите - это oneOf, где каждая подсхема дает действительное состояние для каждого из obj* свойств.Каждое состояние будет выглядеть примерно так:

{
  "properties": {
    "mode": {"const": 1},
    "obj1": {"required": ["a","b"]},
    "obj3": {"required": ["x"]}
  }
}

Создайте одно из них для каждого из состояний, перечисленных в вашем вопросе, и добавьте их все в oneOf, который находится в корне.

Вы могли бы сделать это с if / then / else, но для этого случая я бы предпочел oneOf, чтобы избежать вложения.


Кроме того, я заметил, что у вас есть много лишних $id в середине, которые просто указывают их расположение в схеме.Вы хотите один в корне, но другие вам не нужны.Реализации могут работать с этими ссылками на основе местоположения тривиально.

...