如何基于第二个JSON对象的值使JSON对象的属性必需?

时间:2019-01-24 16:30:05

标签: json jsonschema

我有一个JSON提交,我正在尝试根据模板中定义的许多规则进行验证。该模板定义了许多向用户提出的问题。对于提交,是否需要一个问题答案取决于上一个问题的值。

所以基本上

Do you have a dog? Yes/No
What kind of dog do you have?

第一个问题的有效答案使用枚举来保护,因此用户只能提供yesno字符串作为问题的答案。

如果用户对问题的回答是肯定的,则我需要第二个问题,因此,如果第一个答案为yes时第二个答案留空,则会引发错误。如果第一个答案是no,则用户可以自由地将第二个问题留空。

下面是我目前拥有的JSON模式。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "question3-9": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "enum": [
            "Yes", "No"
          ]
        }
      },
      "if": {
        "properties":{
          "answer": {"enum": ["Yes"]}
        }
      },
      "then": {"requried": "#/definitions/question3-257"}
    },
    "question3-257": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  },
  "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"
                    }
                  },
                  "required": [
                    "257"
                  ]
                }
              }
            }
          },
          "required": [
            "3"
          ]
        }
      }
    }
  }
}

我认为,通过使用JSON-Schema7中提供的if-then-else,我可以将第二个问题设置为必填,但它似乎无法像这样工作。

这是正在使用上述架构验证的提交。

{
  "form_submission": {
    "sections": {
      "3": {
        "questions": {
          "9": {
            "answer": "Yes",
          },
          "257": {
            "answer": "",
          }
        }
      }
    }
  }
}

更新的JSON架构:

"3": {
                "type": "object",
                "properties": {
                  "questions": {
                    "type": "object",
                    "properties": {
                      "9": {
                        "$ref": "#/definitions/question3-9"
                      },
                      "257": {
                        "$ref": "#/definitions/question3-257"
                      }
                    },
                    "if": {
                      "properties":{
                        "answer": {"const": "Home improvements (General)"}
                      }
                    },
                    "then": {"required": ["257"]}
                  }
                }
              }

待验证:

  "3": {
    "questions": {
      "9": {
        "answer": "Home improvements (General)",
      },
      "257": {
        "answer": "", //<-- This is an empty string but should be required since the answer to the abvoe question is "Home improvements (general) as defined with "answer": {"const": "Home improvements (General)"}
      }
    }

1 个答案:

答案 0 :(得分:0)

使用if / then关键字是正确的选择,但是then中的要求并不正确。

required关键字必须是一个字符串数组,每个字符串都表示一个属性名称;在这种情况下,属性名称为“ 257”。

此外,您需要将if / then关键字放在questions属性下,而不是在定义中。通过将其包含在定义中,您需要questions.9属性具有257属性(questions.9.257),但是您需要questions.257属性。< / p>

尝试以下方法:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "question3-9": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "enum": ["Yes", "No"]
        }
      }
    },
    "question3-257": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "minLength": 1
        }
      }
    }
  },
  "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":{
                      "answer": {"const": "Yes"}
                    }
                  },
                  "then": {"required": ["257"]}
                }
              }
            }
          },
          "required": ["3"]
        }
      }
    }
  }
}

此外,我建议在const中使用if关键字。我认为它读起来更明确。