Возможно ли иметь общие свойства перед oneOf?

#json #validation #jsonschema

#json #проверка #jsonschema

Вопрос:

У меня есть эта схема json, в которой есть массив, содержащий несколько объектов, и каждый объект немного отличается от других на основе определенных шаблонов.

Пример.

 [
  {
    "ID": "pgID",
    "Name": "John",
    "Surname": "Doe",
    "ProjectsInvolved": [
      "My Project",
      "My Project 2"
    ]
  },
  {
    "ID": "jtID",
    "Name": "John",
    "Surname": "Doe",
    "WorksOn": [
      "Monday",
      "Thursday"
    ]
  }
]
  

Схема json для этого будет:

 {
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "array",
  "items": {
    "oneOf": [
      {
        "type": "object",
        "properties": {
          "ID": {
            "type": "string",
            "pattern": "^(pg)\w*$"
          },
          "Name": {
            "type": "string"
          },
          "Surname": {
            "type": "string"
          },
          "ProjectsInvolved": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      {
        "type": "object",
        "properties": {
          "ID": {
            "type": "string",
            "pattern": "^(jt)\w*$"
          },
          "Name": {
            "type": "string"
          },
          "Surname": {
            "type": "string"
          },
          "WorksOn": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    ]
  },
  "additionalProperties": false
}
  

Моя проблема в том, что, хотя реальный json похож, в нем гораздо больше элементов, и он будет увеличиваться с течением времени. Поэтому я должен спросить, возможно ли, чтобы схема группировала идентичные элементы Name и Name и имела только ID и массивы в oneOf?

Пример предлагаемой схемы:

 {
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "Name": {
        "type": "string"
      },
      "Surname": {
        "type": "string"
      },
      "oneOf": [
        {
          "ID": {
            "type": "string",
            "pattern": "^(pg)\w*$"
          },
          "ProjectsInvolved": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        {
          "ID": {
            "type": "string",
            "pattern": "^(jt)\w*$"
          },
          "WorksOn": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      ]
    }
  },
  "additionalProperties": false
}
  

Ответ №1:

Как правило, вы хотите заранее определить общий материал и специальные условия после. Это упрощает чтение схемы и приводит к улучшению сообщений об ошибках.

В этом примере, если присутствует «ProjectsInvolved», то «ID» должен начинаться с «pg», а «WorksOn» не может присутствовать. И, если присутствует «WorksOn», то «ID» должен начинаться с «jt», а «ProjectsInvolved» не может присутствовать.

С oneOf or также возможно что-то подобное anyOf , но, как правило, вы получаете лучшие сообщения об ошибках dependencies .

 {
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "ID": { "type": "string" },
      "Name": { "type": "string" },
      "Surname": { "type": "string" },
      "ProjectsInvolved": {
        "type": "array",
        "items": { "type": "string" }
      },
      "WorksOn": {
        "type": "array",
        "items": { "type": "string" }
      }
    },
    "dependencies": {
      "ProjectsInvolved": {
        "properties": {
          "ID": { "pattern": "^(pg)\w*$" }
        },
        "not": { "required": ["WorksOn"] }
      },
      "WorksOn": {
        "properties": {
          "ID": { "pattern": "^(jt)\w*$" }
        },
        "not": { "required": ["ProjectsInvolved"] }
      }
    }
  },
  "additionalProperties": false
}
  

Комментарии:

1. Именно то, что мне было нужно! Я хотел бы дать вам дополнительный 1 только потому, что вас зовут Джейсон, и вы отвечаете на вопрос, связанный с JSON. : D