从外部JSON模式导入所有定义

时间:2016-01-13 16:31:35

标签: jsonschema linked-data json-schema-validator json-schema-defaults

我一直在尝试使用JSON Pointers来引用和重用JSON schemas

根据这些示例,我能够引用在另一个JSON模式中声明的特定属性,一切都按预期进行,但我还没有找到一种方法来扩展基本JSON模式与另一个JSON模式的定义基本模式,而不必显式引用每个属性。

似乎这样会有用,但我还没有发现它是否有可能。

想象一下基础架构things

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing.json",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "url": {
            "id": "url",
            "type": "string",
            "format": "uri"
        },
        "name": {
            "id": "name",
            "type": "string"
        }
    },
    "required": ["name"]
}

如果我想要一个更具体的person架构,它可以重复使用thing的两个属性:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "url": {
            "$ref": "http://example.com/thing.json#/properties/url",
        },
        "name": {
            "$ref": "http://example.com/thing.json#/properties/name",
        },
        "gender": {
            "id": "gender",
            "type": "string",
            "enum": ["F", "M"]
        },
        "nationality": {
            "id": "nationality",
            "type": "string"
        },
        "birthDate": {
            "id": "birthDate",
            "type": "string",
            "format": "date-time"
        }
    },
    "required": ["gender"]
}

然而,我用这种方法看到了两个问题:

  1. 一旦更新超级定义,依赖模式也必须更新
  2. 手动维护所有这些引用变得麻烦/冗长
  3. 规则(如required: name)不是引用定义的一部分
  4. 有没有办法通过使用单个全局引用来获取以下有效的 JSON架构?

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "id": "http://example.com/thing/person.json",
        "type": "object",
        "additionalProperties": false,
        "properties": {
            "url": {
                "id": "url",
                "type": "string",
                "format": "uri"
            },
            "name": {
                "id": "name",
                "type": "string"
            }
            "gender": {
                "id": "gender",
                "type": "string",
                "enum": ["F", "M"]
            },
            "nationality": {
                "id": "nationality",
                "type": "string"
            },
            "birthDate": {
                "id": "birthDate",
                "type": "string",
                "format": "date-time"
            }
        },
        "required": ["name", "gender"]
    }
    

    我尝试在模式的根目录中包含$ref,如下所示:

    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "id": "http://jsonschema.net/thing/person",
        "type": "object",
        "additionalProperties": false,
        "$ref": "http://example.com/thing.json",
        "properties": {
            "gender": {/* ... */},
            "nationality": {/* ... */},
            "birthDate": {/* ... */}
        },
        "required": ["gender"]
    }
    

    这具有继承thing属性但忽略所有其他属性的效果:

    gender: Additional property gender is not allowed
    nationality: Additional property nationality is not allowed
    birthDate: Additional property birthDate is not allowed
    

1 个答案:

答案 0 :(得分:3)

您正在寻找allOf关键字。 JSON Schema不像我们许多人习惯的那样继承。相反,您可以告诉它数据需要对更多父模式(事物)和子模式(父模式)有效。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing.json",
    "type": "object",
    "properties": {
        "url": {
            "id": "url",
            "type": "string",
            "format": "uri"
        },
        "name": {
            "id": "name",
            "type": "string"
        }
    },
    "required": ["name"]
}

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "allOf": [
        { "$ref": "http://example.com/thing.json" },
        {
            "type": "object",
            "properties": {
                "gender": {
                    "id": "gender",
                    "type": "string",
                   "enum": ["F", "M"]
                },
                "nationality": {
                    "id": "nationality",
                    "type": "string"
                },
                "birthDate": {
                    "id": "birthDate",
                    "type": "string",
                    "format": "date-time"
                }
            },
            "required": ["gender"]
        }
    ],
}

或者,正如我所希望的那样,更加简明扼要地写作

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "allOf": [{ "$ref": "http://example.com/thing.json" }],
    "properties": {
        "gender": {
            "id": "gender",
            "type": "string",
            "enum": ["F", "M"]
        },
        "nationality": {
            "id": "nationality",
            "type": "string"
        },
        "birthDate": {
            "id": "birthDate",
            "type": "string",
            "format": "date-time"
        }
    },
    "required": ["gender"]
}

请注意,使用此方法,您无法使用"additionalProperties": false。出于这个原因,我总是建议人们最好的做法是忽略其他属性,而不是明确地禁止它们。