针对包含多个模式定义的 JSON 模式进行验证

validating against a JSON schema containing multiple schema definitions

我正在创建一个 JSON 模式供 Postman 使用,其中包含一些模式定义。我根据模式验证的 JSON 需要与模式定义之一匹配。

示例架构

{
  "oneOf": [
    {
      "$ref": "#/definitions/schema1"
    },
    {
      "$ref": "#/definitions/schema2"
    },
    {
      "$ref": "#/definitions/schema3"
    }
  ],
  "definitions": {
    "schema1": {
      "type": "object",
      "properties": {
        "propertyA": {
          "type": "string"
        }
      },
      "required": [
        "propertyA"
      ]
    },
    "schema2": {
      "type": "object",
      "properties": {
        "propertyB": {
          "type": "string"
        }
      },
      "required": [
        "propertyB"
      ]
    },
    "schema3": {
      "type": "object",
      "properties": {
        "propertyC": {
          "type": "string"
        }
      },
      "required": [
        "propertyC"
      ]
    }
  }
}

样本JSON数据

此 JSON 根据架构进行验证并正确标记为无效(因为需要字符串):

{
    "propertyA": 123
}

问题

这个例子returns 4个错误根据https://www.jsonschemavalidator.net/:

我只对提示需要字符串的错误消息感兴趣。 如何在将架构定义保存在 1 个文件中的同时避免那些其他错误消息?

是的,oneOf 对这种事情来说太糟糕了。 if/then 很冗长,但可以为您提供更好的结果。基本上,您需要确定一些条件来确定架构是否应应用于实例。

通常,该条件是公共字段的值。在这种情况下,如果要验证的实例是具有 "type": "A" 的对象,则它必须针对 /definitions/a 模式进行验证。如果它有 "type": "B" 那么它必须根据 /definitions/b 模式进行验证。

{
  "allOf": [
    {
      "if": {
        "properties": {
          "type": { "const": "A" }
        },
        "required": ["type"]
      },
      "then": { "$ref": "#/definitions/a" }
    },
    {
      "if": {
        "properties": {
          "type": { "const": "B" }
        },
        "required": ["type"]
      },
      "then": { "$ref": "#/definitions/b" }
    }
  ]
}

如果您的条件是特定字段的存在,您可以使用 dependencies 关键字作为快捷方式。如果被验证的实例是一个带有“属性A”属性 的对象,那么该实例必须对 /definitions/a 模式有效。对于“属性B”也是如此。

{
  "dependencies": {
    "propertyA": { "$ref": "#/definitions/a" },
    "propertyB": { "$ref": "#/definitions/b" }
  }
}

您的示例实际上有一个超级简单的解决方案,但我回答了一般情况,因为我假设您的实际架构比示例更复杂。

{
  "type": "object",
  "properties": {
    "propertyA": { "type": "string" },
    "propertyB": { "type": "string" },
    "propertyC": { "type": "string" }
  },
  "oneOf": [
    { "required": ["propertyA"] },
    { "required": ["propertyB"] },
    { "required": ["propertyC"] }
  ]
}