Как выполнить проверку JSON свойств схемы на основе значения перечисления в другом свойстве - PullRequest
0 голосов
/ 12 апреля 2020

На основе заданной схемы JSON. Если мне нужно построить «required» для «DayActivity» на основе «Day», выбранного в DayHeader (например, требуется только PhysicalActivity, если Day is SUNDAY), как мне построить схему JSON? Я пробовал различные подходы, такие как тогда и определения. Когда я генерирую файл JSON на основе схемы JSON, он не может проверить требуемую «DayActivity», выбранную атрибутом «Day». Как мне сослаться на значение, выбранное в другом свойстве, и построить «требуемый»? Цените любые ссылки на этот вопрос.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "DayHeader": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "Day": {
          "type": "string",
          "enum": [
            "SUNDAY",
            "MONDAY",
            "TUESDAY",
            "WEDNESDAY",
            "THURSDAY",
            "FRIDAY",
            "SATURDAY"
          ]
        }
      },
      "required": [
        "day"
      ]
    },
    "ActivityDetail": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "DayActivity": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "PhysicalActivity": {
                "type": "string",
                "enum": [
                  "Walking",
                  "Running"
                ]
              },
              "StudyActivity": {
                "type": "string",
                "enum": [
                  "Maths Class",
                  "Science Class"
                ]
              },
              "ArtActivity": {
                "type": "string",
                "enum": [
                  "Drawing",
                  "Dance"
                ]
              }
            }
          }
        }
      }
    }
  }
}

1 Ответ

1 голос
/ 16 апреля 2020

Вообще говоря, этот вопрос уже имеет удивительный обобщенный c ответ здесь .

При этом, возможно, вы сможете улучшить свою структуру данных в отношении "DayActivity", что также облегчит формулировку соответствующей JSON схемы.


Ваш "DayActivity" в настоящее время является массивом объектов, каждый из которых содержит до трех свойств одновременно: "PhysicalActivity" / "StudyActivity" / "ArtActivity". Как насчет чего-то подобного следующему, вместо этого это позволяет только одному из трех свойств присутствовать в одном элементе массива:

"DayActivity": {
  "type": "array",
  "minItems": 1,
  "items": {
    "type": "object",
    "oneOf": [
      {
        "properties": {
          "PhysicalActivity": {
            "type": "string",
            "enum": ["Walking", "Running"]
          }
        },
        "required": ["PhysicalActivity"]
      },
      {
        "properties": {
          "StudyActivity": {
            "type": "string",
            "enum": ["Maths Class", "Science Class"]
          }
        },
        "required": ["StudyActivity"]
      },
      {
        "properties": {
          "ArtActivity": {
            "type": "string",
            "enum": ["Drawing", "Dance"]
          }
        },
        "required": ["ArtActivity"]
      }
    ]
  },
  "contains": {
    "required": ["PhysicalActivity"]
  }
}

Обратите внимание на ключевое слово "contains" в конце, чтобы гарантировать, что всегда нужно быть хотя бы одной записью "PhysicalActivity" в массиве "DayActivity".

Если вы теперь хотите условно применять "StudyActivity" в каждый день недели, но "SUNDAY", вы можете добавить следующее в основную схему ( то есть на верхнем уровне, где объявляется "properties": { "DayHeader": ... }:

"oneOf": [
  {
    "properties": {
      "DayHeader": {
        "properties": {
          "Day": {
            "const": "SUNDAY"
          }
        }
      }
    }
  },
  {
    "properties": {
      "DayHeader": {
        "properties": {
          "Day": {
            "enum": [
              "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"
            ]
          }
        }
      },
      "ActivityDetail": {
        "properties": {
          "DayActivity": {
            "contains": {
              "required": ["StudyActivity"]
            }
          }
        }
      }
    }
  }
]

Полная схема может выглядеть примерно так:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["DayHeader", "ActivityDetail"],
  "properties": {
    "DayHeader": {
      "type": "object",
      "properties": {
        "Day": {
          "type": "string",
          "enum": [
            "SUNDAY",
            "MONDAY",
            "TUESDAY",
            "WEDNESDAY",
            "THURSDAY",
            "FRIDAY",
            "SATURDAY"
          ]
        }
      },
      "required": [
        "Day"
      ]
    },
    "ActivityDetail": {
      "type": "object",
      "required": ["DayActivity"],
      "properties": {
        "DayActivity": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "oneOf": [
              {
                "properties": {
                  "PhysicalActivity": {
                    "type": "string",
                    "enum": ["Walking", "Running"]
                  }
                },
                "required": ["PhysicalActivity"]
              },
              {
                "properties": {
                  "StudyActivity": {
                    "type": "string",
                    "enum": ["Maths Class", "Science Class"]
                  }
                },
                "required": ["StudyActivity"]
              },
              {
                "properties": {
                  "ArtActivity": {
                    "type": "string",
                    "enum": ["Drawing", "Dance"]
                  }
                },
                "required": ["ArtActivity"]
              }
            ]
          },
          "contains": {
            "required": ["PhysicalActivity"]
          }
        }
      }
    }
  },
  "oneOf": [
    {
      "properties": {
        "DayHeader": {
          "properties": {
            "Day": {
              "const": "SUNDAY"
            }
          }
        }
      }
    },
    {
      "properties": {
        "DayHeader": {
          "properties": {
            "Day": {
              "enum": [
                "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"
              ]
            }
          }
        },
        "ActivityDetail": {
          "properties": {
            "DayActivity": {
              "contains": {
                "required": ["StudyActivity"]
              }
            }
          }
        }
      }
    }
  ]
}

Выше успешно проверяется по:

{
  "DayHeader": { "Day": "SUNDAY"},
  "ActivityDetail": {
    "DayActivity": [
      { "PhysicalActivity": "Walking" }
    ]
  }
}

Но не по следующему (потому что отсутствует "StudyActivity":

{
  "DayHeader": { "Day": "WEDNESDAY"},
  "ActivityDetail": {
    "DayActivity": [
      { "PhysicalActivity": "Walking" }
    ]
  }
}
...