0

我正在尝试找到一种方法来更改架构验证以找到最适合给定对象的架构。假设我们有一个模式:

{
  "oneOf": [
    {
      "$ref": "#/definitions/a"
    },
    {
      "$ref": "#/definitions/b"
    }
  ],
  "definitions": {
    "a": {
      "type": "object",
      "properties": {
        "prop1": {
          "enum": ["x"]
        }
      },
      "required": ["prop1"]
    },
    "b": {
      "type": "object",
      "properties": {
        "prop1": {
          "enum": ["y"]
        },
        "prop2": {
          "type": "string"
        }
      },
      "required": ["prop1", "prop2"]
    }
  }
}

现在,如果我有一个 object { "prop1": "y" },我希望它被解析为#/definitions/b类型,即使它对于这个方案并不真正有效。也就是说,我只想使用prop1属性来解决。

我想知道是否有办法使用 AJV 自定义关键字来做到这一点,而无需重建架构本身?特别是,如果模式对对象无效,是否可以使用自定义关键字来覆盖它并使其有效?

4

1 回答 1

1

如果目标是只报告正确模式中的错误,您可以使用“switch”(使用 v5 选项,它从 5.0.0 版本移至ajv-keywords)或“if/then/else”(推荐为它很可能会添加到 JSON Schema 草案 7) 中:

{
  "id": "schema",
  "if": { "properties": { "prop1": { "const": "x" } } },
  "then": { "$ref": "#/definitions/a" },
  "else": { "$ref": "#/definitions/b" }
}

如果您需要知道用于验证的架构,您可以使用自定义关键字来记录它:

{
  "id": "schema",
  "if": { "properties": { "prop1": { "const": "x" } } },
  "then": {
    "allOf": [
     { "schemaUsed": "schema#/definitions/a" },
     { "$ref": "#/definitions/a" }
    ]
  },
  "else": {
    "allOf": [
     { "schemaUsed": "schema#/definitions/b" },
     { "$ref": "#/definitions/b" }
    ]
  }
}

应定义关键字以在验证期间将模式 ID 存储在某个变量中,以便在验证后您可以看到使用了哪个。

如果您需要获取实际架构,您可以执行以下操作:

var validate = ajv.getSchema('schema#/definitions/a'); // validating function
var schema = validate.schema; // schema as JSON
于 2017-01-04T15:20:32.600 回答