基于 ENUM 值的验证 JSON 子模式定义

Validation JSON subschema definition based on ENUM value

我正在尝试验证并报告构建过程的 JSON 架构错误。

基于 type 枚举,我想针对特定的子模式进行验证并报告该模式的错误。

如果 type 属性是 "weblogic" 那么我只想验证 "weblogic" 子模式定义。如果类型为 tomcat

,则执行相同的操作

这是我当前的模式

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "#",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "middleware"
  ],
  "properties": {
    "middleware": {
      "$ref": "#/definitions/middleware"
    }
  },
  "definitions": {
    "middleware":{
      "type": "array",
      "items": {
        "oneOf":[
          {"$ref": "#/definitions/weblogic"},
          {"$ref": "#/definitions/tomcat"}
        ],
        "required": ["type","buildInfo"]
      }
    },
    "weblogic": {
      "properties": {
        "type": {"const": "weblogic"},
        "buildInfo": {
          "properties": {
            "adminSslPort": {
              "type": "integer"
            }
          },
          "additionalProperties": false,
          "required": ["adminSslPort"]
        }
      }
    },
    "tomcat":{
      "properties": {
        "type": {"const": "tomcat"},
        "buildInfo":{
          "properties": {
            "classpath": {
              "type": "string"
            }
          },
          "additionalProperties": false,
          "required": ["classpath"]
        }
      }
    }
  }
}

还有我的 JSON 有效载荷

{
    "middleware":[
        {
            "type": "weblogic",
            "buildInfo":{
                "adminSslPort": 7002
            }
        },
        {
            "type": "tomcat",
            "buildInfo":{

            }
        }
    ]
}

现在我预计这会失败,因为 buildInfo 对象缺少 classpath 属性,并且它确实无法通过验证。 但是我得到的错误包括针对 "weblogic" 定义的验证错误。

[
    {
        "pointerToViolation": "#/middleware/1",
        "causingExceptions": [
            {
                "schemaLocation": "#/definitions/weblogic",
                "pointerToViolation": "#/middleware/1",
                "causingExceptions": [
                    {
                        "schemaLocation": "#/definitions/weblogic/properties/buildInfo",
                        "pointerToViolation": "#/middleware/1/buildInfo",
                        "causingExceptions": [],
                        "keyword": "required",
                        "message": "required key [adminSslPort] not found"
                    },
                    {
                        "schemaLocation": "#/definitions/weblogic/properties/type",
                        "pointerToViolation": "#/middleware/1/type",
                        "causingExceptions": [],
                        "keyword": "const",
                        "message": ""
                    }
                ],
                "message": "2 schema violations found"
            },
            {
                "schemaLocation": "#/definitions/tomcat/properties/buildInfo",
                "pointerToViolation": "#/middleware/1/buildInfo",
                "causingExceptions": [],
                "keyword": "required",
                "message": "required key [classpath] not found"
            }
        ],
        "keyword": "oneOf",
        "message": "#: 0 subschemas matched instead of one"
    }
]

有没有办法只针对 type 匹配的子模式进行验证?

您可以使用 ifthen 关键字,如下所示。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "#",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "middleware"
  ],
  "properties": {
    "middleware": {
      "$ref": "#/definitions/middleware"
    }
  },
  "definitions": {
    "middleware":{
      "type": "array",
      "items": {
        "type": "object",
        "allOf": [
          {"$ref": "#/definitions/weblogic"},
          {"$ref": "#/definitions/tomcat"}
        ],
        "required": ["type","buildInfo"]
      }
    },
    "weblogic": {
      "if": {
        "properties": {
          "type": {
            "const": "weblogic"
          }
        }
      },
      "then": {
        "properties": {
          "buildInfo": {
            "properties": {
              "adminSslPort": {
                "type": "integer"
              }
            },
            "additionalProperties": false,
            "required": ["adminSslPort"]
          }
        }
      }
    },
    "tomcat":{
      "if": {
        "properties": {
          "type": {
            "const": "tomcat"
          }
        }
      },
      "then": {
        "properties": {
          "buildInfo":{
            "properties": {
              "classpath": {
                "type": "string"
              }
            },
            "additionalProperties": false,
            "required": ["classpath"]
          }
        }
      }
    }
  }
}