JSONSchema v4 - 解析模式引用时出错 - 定义和参考

JSONSchema v4 - Error when resolving schema reference - Definitions and References

尝试使用 http://www.jsonschemavalidator.net/

验证以下架构时
{
    "id": "http://some.site.somewhere/entry-schema#",
    "$schema": "http://json-schema.org/draft-04/schema#",
    "description": "schema for the FormularSpecification",
    "definitions": {
        "elementId": {
            "id": "http://jsonschema.net/elementId",
            "type": "string"
        },
        "mappingKey": {
            "id": "http://jsonschema.net/mappingKey",
            "type": "string"
        },
        "elementType": {
            "id": "http://jsonschema.net/elementType",
            "type": "string"
        },
        "length": {
            "id": "http://jsonschema.net/length",
            "type": "integer"
        },
        "label": {
            "id": "http://jsonschema.net/label",
            "type": "string"
        },
        "content": {
            "id": "http://jsonschema.net/content",
            "type": "string"
        },
        "placeholder": {
            "id": "http://jsonschema.net/placeholder",
            "type": "string"
        },
        "date": {
            "id": "http://jsonschema.net/date",
            "type": "string"  
        },
        "option": {
            "id": "http://jsonschema.net/option",
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" },
                "label": { "$ref": "#/definitions/label" }
            },
            "required": ["elementId", "label"]
        },
        "options": {
            "id": "http://jsonschema.net/options",
            "type": "array",
            "items": { "$ref": "#/definitions/option" },
            "minItems": 1,
            "uniqueItems": true
        },
        "textfield": {
            "id": "http://jsonschema.net/textfield",
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" },
                "length": { "$ref": "#/definitions/length" },
                "label": { "$ref": "#/definitions/label" },
                "placeholder": { "$ref": "#/definitions/placeholder" },
                "textfieldType": {
                    "enum": [ "text", "ext4", "btrfs" ]
                }
            },
            "required": ["elementId", "length", "label", "placeholder", "textfieldType"]
        },
        "checkbox": {
            "id": "http://jsonschema.net/checkbox",
            "type": "object",
            "properties": {
                "label": { "$ref": "#/definitions/label" }
            },
            "required": ["label"]
        },
        "radio": {
            "id": "http://jsonschema.net/radio",
            "type": "object",
            "properties": {
                "label": { "$ref": "#/definitions/label" },
                "options": { "$ref": "#/definitions/options" }
            },
            "required": ["label", "options"]
        },
        "dropdown": {
            "id": "http://jsonschema.net/dropdown",
            "type": "object",
            "properties": {
                "label": { "$ref": "#/definitions/label" },
                "options": { "$ref": "#/definitions/options" }
            },
            "required": ["label", "options"]
        },
        "validator": {
            "id": "http://jsonschema.net/validator",
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" }
            }
        },
        "validators": {
            "id": "http://jsonschema.net/validators",
            "type": "array",
            "items": { "$ref": "#/definitions/validator" }
        },
        "interactiveDetails": {
            "type": "object",
            "oneOf": [
                { "textfield": { "$ref": "#/definitions/textfield" } },
                { "checkbox": { "$ref": "#/definitions/checkbox" } },
                { "radio": { "$ref": "#/definitions/radio" } },
                { "dropdown": { "$ref": "#/definitions/dropdown" } },
                { "date": { "$ref": "#/definitions/date" } }
            ]
        },
        "interactive": {
            "id": "http://jsonschema.net/interactive",
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" },
                "elementType": { "$ref": "#/definitions/elementType" },
                "mappingKey": { "$ref": "#/definitions/mappingKey" },
                "validators": { "$ref": "#/definitions/validators" },
                "interactiveDetails" : { "$ref": "#/definitions/interactiveDetails" }
            },
            "required": ["elementId", "elementType", "mappingKey", "validators"]
        },
        "interactives": {
            "id": "http://jsonschema.net/interactives",
            "type": "array",
            "items": { "$ref": "#/definitions/interactive" }
        },
        "description": {
            "id": "http://jsonschema.net/description",
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" },
                "elementType": { "$ref": "#/definitions/elementType" },
                "content": { "$ref": "#/definitions/content" }
            },
            "required": ["elementId", "elementType", "content"]
        },
        "descriptions": {
            "items": { "$ref": "#/definitions/description" }
        },
        "children": {
            "items": { 
                "anyOf": [
                    { "$ref": "#/definitions/group" },
                    { "$ref": "#/definitions/question" }
                ]
            },
            "minItems": 1
        },
        "question": {
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" },
                "descriptions": { "$ref": "#/definitions/descriptions" },
                "interactives": { "$ref": "#/definitions/interactives" }
            },
            "required": ["elementId", "descriptions", "interactives"]
        },
        "group": {
            "type": "object",
            "properties": {
                "elementId": { "$ref": "#/definitions/elementId" },
                "descriptions": { "$ref": "#/definitions/descriptions" },
                "children": { "$ref": "#/definitions/children"}
            },
            "required": ["elementId", "descriptions", "children"]
        }
    },
    "type": "object",
    "properties": {
        "elementId": { "$ref": "#/definitions/elementId" },
        "description": { "$ref": "#/definitions/descriptions" },
        "children": { "$ref": "#/definitions/children" }
    },
    "required": [
        "elementId",
        "descriptions",
        "children"
    ]
}

我收到以下错误:

Error when resolving schema reference '#/definitions/elementId'. Path 'definitions.description.properties.elementId', line 135, position 30.

我不知道是什么问题。翻了好几遍文档,也看了教程,但是一点头绪都没有。

id 关键字的语义有点混乱。我不确定我自己是否完全理解它。一般来说,在架构的根以外的任何地方包含 id 几乎都不是一个好主意。

The "id" keyword (or "id", for short) is used to alter the resolution scope. When an id is encountered, an implementation MUST resolve this id against the most immediate parent scope. The resolved URI will be the new resolution scope for this subschema and all its children, until another id is encountered.

考虑以下来自您的架构的摘录。因为您包含了 id 关键字,所以您的“elementId”和“label”$ref 不会像您期望的那样根据文档的根进行解析,它们会从最近的父架构 id.

"option": {
    "id": "http://jsonschema.net/option",
    "type": "object",
    "properties": {
        "elementId": { "$ref": "#/definitions/elementId" },
        "label": { "$ref": "#/definitions/label" }
    },
    "required": ["elementId", "label"],
    "definitions": { ... }  <-- your $refs expect values here
    }
},

我看到在某些圈子中,人们为每个子模式编写带有 id 的模式。我不确定他们认为这样做有什么好处,但我怀疑他们认为 id 只是一个标签,不明白它如何改变分辨率范围。

如果你确实有充分的理由在任何地方使用 ids 并且想保留它们,当你有冲突时你总是可以显式引用根 id

{ "$ref": "http://some.site.somewhere/entry-schema#definitions/elementId" }