多个If-Then-Else无法验证JSON模式

时间:2019-02-14 16:27:24

标签: json jsonschema

我有一个内置的程序,该程序需要一个JSON对象,并根据输入的详细信息生成一个JSON模式文件。当我使用此程序为较小的JSON对象生成架构时,该架构可以正常工作并按预期进行验证。在这种较小的模式中,只有一个if-then-else块。

但是,当我尝试生成使用多个if-then-else块的架构时,if-then-else验证似乎完全停止工作,并且将允许任何事情通过。

为了更加清楚,我将在下面发布一个示例。

JSON模式

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "question6-99": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "enum": ["Yes", "No"]
        }
      }
    },
    "question6-100": {
      "type": "object",
      "properties": {
        "answer": {
          "type": "string",
          "enum": ["Mr","Ms","Mrs","Miss","Dr","Rev","Sir","Lady","Lord","Prof", ""]
        }
      }
    }
  },
  "type": "object",
  "properties": {
    "form_submission": {
      "type": "object",
      "properties": {
        "sections": {
          "type": "object",
          "properties": {
            "6": {
              "type": "object",
              "properties": {
                "questions": {
                  "type": "object",
                  "properties": {
                    "99": {
                      "$ref": "#/definitions/question6-99"
                    },
                    "100": {
                      "$ref": "#/definitions/question6-100"
                    }
                  },
                  "if": {
                    "properties": {
                      "99": {
                        "properties": {
                          "answer": {
                            "enum": [
                              "Yes"
                            ]
                          }
                        },
                        "required": [
                          "answer"
                        ]
                      }
                    },
                    "required": [
                      "100"
                    ]
                  },
                  "then": {
                    "properties": {
                      "100": {
                        "properties": {
                          "answer": {
                            "minLength": 1
                          }
                        }
                      }
                    }
                  },
                  "else": {
                    "properties": {
                      "100": {
                        "properties": {
                          "answer": {
                            "maxLength": 0
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "required": [
            "6"
          ]
        }
      }
    }
  }
}

正在验证的JSON对象

{
  "form_submission": {
    "sections": {
      "1": {
        "questions": {
          "99": {
            "answer": "Yes",
          },
          "100": {
            "answer": "",
          }
        }
      }
    }
  }
}

对于上面的示例,如果使用架构验证对象,则当问题99的答案为“是”时,必须回答问题100的答案。这可以正常工作。

但是,如果我随后尝试使用下面的架构,该架构针对第二个JSON对象使用两个if-then-else块,则不会发生if-then-else验证。

我只是想知道我的模式代码结构是否做错了什么,从而阻止了验证的正确进行。

使用两个If-then-else的架构

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "question6-99": {
            "type": "object",
            "properties": {
                "answer": {
                    "type": "string",
                    "minLength": 1,
                    "enum": ["Yes", "No"]
                }
            }
        },
        "question6-100": {
            "type": "object",
            "properties": {
                "answer": {
                    "type": "string",
                    "enum": ["Mr", "Ms", "Mrs", "Miss", "Dr", "Rev", "Sir", "Lady", "Lord", "Prof", ""]
                }
            }
        },
        "question6-101": {
            "type": "object",
            "properties": {
                "answer": {
                    "type": "string"
                }
            }
        }
    },
    "type": "object",
    "properties": {
        "form_submission": {
            "type": "object",
            "properties": {
                "sections": {
                    "type": "object",
                    "properties": {
                        "6": {
                            "type": "object",
                            "properties": {
                                "questions": {
                                    "type": "object",
                                    "properties": {
                                        "99": {
                                            "$ref": "#/definitions/question6-99"
                                        },
                                        "100": {
                                            "$ref": "#/definitions/question6-100"
                                        },
                                        "101": {
                                            "$ref": "#/definitions/question6-101"
                                        }
                                    },
                                    "required": ["99", "100", "101", "102", "103", "104", "105", "111"],
                                    "if": {
                                        "properties": {
                                            "99": {
                                                "properties": {
                                                    "answer": {
                                                        "enum": ["Yes"]
                                                    }
                                                },
                                                "required": ["answer"]
                                            }
                                        },
                                        "required": ["100"]
                                    },
                                    "then": {
                                        "properties": {
                                            "100": {
                                                "properties": {
                                                    "answer": {
                                                        "minLength": 1
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "else": {
                                        "properties": {
                                            "100": {
                                                "properties": {
                                                    "answer": {
                                                        "maxLength": 0
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "if": {
                                        "properties": {
                                            "99": {
                                                "properties": {
                                                    "answer": {
                                                        "enum": ["Yes"]
                                                    }
                                                },
                                                "required": ["answer"]
                                            }
                                        },
                                        "required": ["101"]
                                    },
                                    "then": {
                                        "properties": {
                                            "101": {
                                                "properties": {
                                                    "answer": {
                                                        "minLength": 1
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "else": {
                                        "properties": {
                                            "101": {
                                                "properties": {
                                                    "answer": {
                                                        "maxLength": 0
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "required": ["1"]
                }
            }
        }
    }
}

第二个验证模式

{
    "form_submission": {
        "id": "80035",
        "status": "Incomplete",
        "validated": true,
        "failure_reason": "",
        "sections": {

            "1": {
                "questions": {
                    "99": {
                        "answer": "Yes",
                        "web_validated": true,
                        "web_error_string": "",
                        "server_error_string": ""
                    },
                    "100": {
                        "answer": "",
                        "web_validated": true,
                        "web_error_string": "",
                        "server_error_string": ""
                    },
                    "101": {
                        "answer": "Yes",
                        "web_validated": true,
                        "web_error_string": "",
                        "server_error_string": ""
                    }
                },
                "name": "",
                "validated": true,
                "server_validated": true,
                "notes": ""
            }
        },
        "submitted_section_id": 11
    }
}

将allOf添加到架构

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {
        "question6-99": {
            "type": "object",
            "properties": {
                "answer": {
                    "type": "string",
                    "minLength": 1,
                    "enum": ["Yes", "No"]
                }
            }
        },
        "question6-100": {
            "type": "object",
            "properties": {
                "answer": {
                    "type": "string",
                    "enum": ["Mr", "Ms", "Mrs", "Miss", "Dr", "Rev", "Sir", "Lady", "Lord", "Prof", ""]
                }
            }
        },
        "question6-101": {
            "type": "object",
            "properties": {
                "answer": {
                    "type": "string"
                }
            }
        }
    },
    "type": "object",
    "properties": {
        "form_submission": {
            "type": "object",
            "properties": {
                "sections": {
                    "type": "object",
                    "properties": {
                        "6": {
                            "type": "object",
                            "properties": {
                                "questions": {
                                    "type": "object",
                                    "properties": {
                                        "99": {
                                            "$ref": "#/definitions/question6-99"
                                        },
                                        "100": {
                                            "$ref": "#/definitions/question6-100"
                                        },
                                        "101": {
                                            "$ref": "#/definitions/question6-101"
                                        }
                                    },
                                    "required": ["99", "100", "101", "102", "103", "104", "105", "111"],
                                    "allOf": [
                                      {
                                        "if": {
                                            "properties": {
                                                "99": {
                                                    "properties": {
                                                        "answer": {
                                                            "enum": ["Yes"]
                                                        }
                                                    },
                                                    "required": ["answer"]
                                                }
                                            },
                                            "required": ["100"]
                                        },
                                        "then": {
                                            "properties": {
                                                "100": {
                                                    "properties": {
                                                        "answer": {
                                                            "minLength": 1
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        "else": {
                                            "properties": {
                                                "100": {
                                                    "properties": {
                                                        "answer": {
                                                            "maxLength": 0
                                                        }
                                                    }
                                                }
                                            }
                                        }},
                                      {
                                        "if": {
                                            "properties": {
                                                "99": {
                                                    "properties": {
                                                        "answer": {
                                                            "enum": ["Yes"]
                                                        }
                                                    },
                                                    "required": ["answer"]
                                                }
                                            },
                                            "required": ["101"]
                                        },
                                        "then": {
                                            "properties": {
                                                "101": {
                                                    "properties": {
                                                        "answer": {
                                                            "minLength": 1
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        "else": {
                                            "properties": {
                                                "101": {
                                                    "properties": {
                                                        "answer": {
                                                            "maxLength": 0
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                      }
                                    ]
                                }
                            }
                        }
                    },
                    "required": ["1"]
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果我们除去复杂的部分,我认为问题就很清楚了。

Names

在JSON中,重复键的值未定义。 JSON解析器将忽略其中的(?<=Name: ).+?(?=Age)和其中{ "if": { ... }, "then": { ... }, "if": { ... }, "then": { ... } } 之一。

您可以通过将if包裹在then中来解决此问题。

if

优良作法是始终将allOf / { "allOf": [ { "if": { ... }, "then": { ... } }, { "if": { ... }, "then": { ... } } ] } / if包装在then中,即使您只有一个。这是因为根据定义,JSON对象是无序的。因此,某些工具可能会重新排列您的关键字,从而使elseallOf分开,从而使架构难以解读。

if