Схема JSON `required` позволяет использовать пустую строку для значения

Я использую шаблон схемы JSON для проверки данных, полученных с помощью онлайн-формы. Одним из требований валидатора является то, что он позволяет требовать некоторые вопросы на основе ответов, данных на другие вопросы.

Например, если вопрос - Do you want a loan?, а пользователь отвечает yes, тогда для ответа на вопрос What is the loan to be used for? необходимо установить значение «Требуется», чтобы пользователь должен был дать ответ. Если ответ no, то второй вопрос не требуется.

Я использую определения для определения своих вопросов, а затем ссылаюсь на них ниже в основной схеме вопросов. Я читал, что, используя функцию if-then-else, представленную в draft-07, я мог бы использовать ее, чтобы задать определенные вопросы, которые потребуются на основе ответов на другие вопросы.

В этом конкретном случае я бы хотел, чтобы если пользователь вводил ответ Home improvements (General) на вопрос 9, тогда вопрос 257 будет установлен как обязательный и ДОЛЖЕН быть дан ответ, в противном случае должна быть выдана ошибка.

В настоящий момент, когда я ввожу этот валидатор в https://www.jsonschemavalidator.net/, он не работать как положено. На самом деле происходит то, что ответ на вопрос 257 можно оставить пустым, даже если ответ на вопрос 9 - «Усовершенствования дома (общие).

Как я могу изменить мою схему, чтобы добиться желаемого поведения?

Схема JSON

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "question3-9": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "enum": [
            "Home improvements (General)",
            "Other"
          ]
        }
      }
    },
    "question3-257": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
        }
      }
    }
  },
  "type": "object",
  "properties": {
    "form_submission": {
      "type": "object",
      "properties": {
        "sections": {
          "type": "object",
          "properties": {
            "3": {
              "type": "object",
              "properties": {
                "questions": {
                  "type": "object",
                  "properties": {
                    "9": {
                      "$ref": "#/definitions/question3-9"
                    },
                    "257": {
                      "$ref": "#/definitions/question3-257"
                    }
                  },
                  "if": {
                    "properties": {
                      "9": {
                        "properties": {
                          "answer": {
                            "enum": [
                              "Home improvements (General)"
                            ]
                          }
                        }
                      }
                    }
                  },
                  "then": {
                    "required": [
                      "257"
                    ]
                  }
                }
              }
            }
          },
          "required": [
            "3"
          ]
        }
      }
    }
  }
}

JSON для проверки:

{
  "form_submission": {
    "sections": {
      "3": {
        "questions": {
          "9": {
            "answer": "Home improvements (General)",
          },
          "257": {
            "answer": "",
          }
        }
      }
    }
  }
}

Обновлено If-Then

"if": {
  "properties": {
    "9": {
      "properties": {
        "answer": {
          "enum": [
            "Home improvements (General)"
          ]
        }
      },
      "required": ["answer"]
    }
  },
  "required": ["9"]
},
"then": {
  "257": {
    "properties":{
      "answer":{
        "minLength": 1
      }
    }
  }
}

person Jake12342134    schedule 28.01.2019    source источник
comment
stackoverflow.com/questions/38717933/   -  person tom redfern    schedule 29.01.2019
comment
OP не имел проблем с применимостью, но скорее неправильно понял, как применяется required, и что значение then должно быть схемой.   -  person Relequestual    schedule 30.01.2019


Ответы (1)


Ваша проблема здесь в том, что вы ожидаете, что required проверит значение ключа, а это не так.

Требуется из текущей спецификации draft-7:

Экземпляр объекта действителен для этого ключевого слова, если каждый элемент в массиве является именем свойства в экземпляре.

Это означает, что required проверяет только наличие ключа для объекта. Это не связано со стоимостью. Для проверки строки см. Ключевые слова проверки, применимые к строкам. Я подозреваю, что вы хотите minLength или pattern (что является регулярным выражением).

https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.3

person Relequestual    schedule 29.01.2019
comment
Привет, я обновил свой If-Then в моей схеме, но, похоже, он по-прежнему не обеспечивает правильного соблюдения minLength ответа на вопрос 257. Правильно ли я ссылаюсь на поле answer в моем предложении then? Я обновил OP своим новым If-Then внизу. - person Jake12342134; 30.01.2019
comment
В ПОРЯДКЕ. Я отладил схему, сначала проверив вашу if оценку условия, сделав then равным false. Значение then должно быть схемой ... поэтому, если вы возьмете значение then самостоятельно, вы увидите, что оно не добавляет никаких ограничений проверки, потому что вам нужно обернуть 257 в properties. - person Relequestual; 30.01.2019
comment
очень хороший ответ. Разница между required и string contraints. Как и ps, required принудительно применяется, если поле равно null, но не когда оно пусто. Если вы спросите меня, этот ответ следует выбрать как правильный. - person myuce; 24.03.2020