多个 If-Then-Else 未验证 JSON 模式

Jak*_*134 4 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"
          ]
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

正在验证 JSON 对象

{
  "form_submission": {
    "sections": {
      "1": {
        "questions": {
          "99": {
            "answer": "Yes",
          },
          "100": {
            "answer": "",
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

对于上面的示例,如果使用模式来验证对象,则必须在问题 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"]
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要验证的第二个模式

{
    "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
    }
}
Run Code Online (Sandbox Code Playgroud)

将 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"]
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*ers 14

如果我们去掉复杂的部分,我想问题就清楚了。

{
  "if": { ... },
  "then": { ... },
  "if": { ... },
  "then": { ... }
}
Run Code Online (Sandbox Code Playgroud)

在 JSON 中,重复键的值是未定义的。这些ifs 之一和这些thens 之一将被 JSON 解析器忽略。

您可以通过将ifs包装在allOf.

{
  "allOf": [
    {
      "if": { ... },
      "then": { ... }
    },
    {
      "if": { ... },
      "then": { ... }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

这是很好的做法,始终换你if/ then/elseallOf,即使你只有一个。这是因为 JSON 对象根据定义是无序的。因此,某些工具可能会重新排列您的关键字,以一种使模式难以破译的方式拆分ifs 和thens。

{
  "definitions": {},
  "else": {},
  "if": {},
  "properties": {},
  "then": {},
  "type": "object",
}
Run Code Online (Sandbox Code Playgroud)