针对AJV

时间:2017-01-04 12:25:59

标签: javascript validation jsonschema ajv

我试图找到一种方法来改变模式验证,以便为给定对象找到最合适的模式。我们假设我们有一个架构:

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

现在,如果我有一个对象{ "prop1": "y" },我希望它从#/definitions/b类型解析,即使它对此方案不是真的有效。也就是说,我想只使用prop1属性来解析。

我想知道是否有办法使用AJV自定义关键字,而无需重建架构本身?特别是,如果schema对某个对象无效,是否可以使用自定义关键字覆盖它并使其有效?

1 个答案:

答案 0 :(得分: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