首页 > 解决方案 > Json Schema - oneOf 与通配符路径的引用?

问题描述

我想组织我的模式的定义部分来分组许多类似的定义。在下面的示例中,我有一个具有“ipv4”和“ipv6”子定义的“ipAddress”组。(您可以想象为标识某些区域的 ip 范围添加更多子定义等)

{
    "definitions": {
        "generalType": {
            "ipAddress": {
                "ipv4": {
                    "type": "object",
                    "properties": {
                      "address": {
                        "type":"string",
                        "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"
                      },
                      "generalType": {
                        "type": "string",
                        "default": "ipAddress"
                      },
                      "specificType": {
                        "type": "string",
                        "default": "ipv4"
                      }
                    }
                },
                "ipv6": {
                    "type": "object",
                    "properties": {
                      "address": {
                        "type":"string",
                        "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$"
                      },
                      "generalType": {
                        "type": "string",
                        "default": "ipAddress"
                      },
                      "specificType": {
                        "type": "string",
                        "default": "ipv6"
                      }
                    }
                }
            }
        }
    },
    "type": "object",
    "additionalProperties": false,
    "required": ["ipAddress"],
    "properties": {
        "ipAddress": {
            "oneOf": [{
                "$ref": "#/definitions/generalType/ipAddress/ipv4"
            },{
                "$ref": "#/definitions/generalType/ipAddress/ipv6"
            }]
        }
    }
}

我想避免做的是枚举"oneOf"属性中的每个子定义。

换句话说,而不是

"oneOf": [
  {
    "$ref": "#/definitions/generalType/ipAddress/ipv4"
  },{
    "$ref": "#/definitions/generalType/ipAddress/ipv6"
  }
]

我宁愿做

"oneOf": {
  "$ref": "#/definitions/logicalType/ipAddress/*"
}

有什么办法吗?

标签: jsonjsonschema

解决方案


不,引用使用 json-pointer。

此外,即使可以,也不能$ref用作 的子级oneOf,因为 的值oneOf必须是数组。

$ref根据 JSON Schema 规范,只能用于代替子模式,而不仅仅是您喜欢的 JSON Schema 中的任何地方。

您可以改为创建一个新定义,如下所示...

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "ipv4": {...},
    "ipv6": {...}
    "ipAddress": {
      "oneOf": [{
          "$ref": "#/definitions/ipv4"
      },{
          "$ref": "#/definitions/ipv6"
      }]
    }
  }
  "properties": {
    "anIPAddress": {
      "$ref": "#/definitions/ipAddress"
    }
  }
}

另请注意,您的定义不能有多个层。如果想进一步分离定义,您可以将其分成多个文件。


推荐阅读