Несколько If-Then-Else не проверяется для схемы JSON - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть программа, которую я построил, которая принимает объект 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": "",
          }
        }
      }
    }
  }
}

ДляПриведенный выше пример, если схема используется для проверки объекта, ответ на вопрос 100 должен быть получен, когда на вопрос 99 получен ответ «да».Это работает правильно.

Однако если я тогда попытаюсь использовать схему ниже, которая использует два блока if-then-else со вторым объектом JSON, проверка if-then-else не произойдет.

I'mпросто интересно, сделал ли я что-то не так со структурой кода моей схемы, которая мешает валидации правильности.

Схема с использованием двух 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"]
                }
            }
        }
    }
}

Вторая схема дляvalidate

{
    "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
    }
}

Добавлено все в схему

{
    "$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 голосов
/ 15 февраля 2019

Если мы удалим сложные биты, я думаю, что проблема станет ясной.

{
  "if": { ... },
  "then": { ... },
  "if": { ... },
  "then": { ... }
}

В JSON значение дублированных ключей не определено.Один из этих if s и один из этих then s будут игнорироваться анализатором JSON.

Вы можете обойти эту проблему, заключив свои if s в allOf.

{
  "allOf": [
    {
      "if": { ... },
      "then": { ... }
    },
    {
      "if": { ... },
      "then": { ... }
    }
  ]
}

Хорошей практикой является всегда оборачивать if / then / else в allOf, даже если у вас есть только один.Это потому, что объект JSON по определению неупорядочен.Поэтому какой-либо инструмент может изменить ваши ключевые слова, разделяя if s и then s таким образом, что схема будет трудно расшифровать.

{
  "definitions": {},
  "else": {},
  "if": {},
  "properties": {},
  "then": {},
  "type": "object",
}
...