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

时间:2016-01-24 17:07:13

标签: jsonschema json-schema-validator

尝试使用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.

我无法弄清问题是什么。我多次扫描文档并查看了教程,但我没有任何线索。

1 个答案:

答案 0 :(得分:1)

id关键字的语义有点令人困惑。我不确定自己完全理解它。通常,将id包含在模式的根目录之外的任何地方几乎都不是一个好主意。

  

“id”关键字(或“id”,简称“)”用于更改分辨率范围。遇到id时,实现必须针对最直接的父作用域解析此id。解析的URI将是此子模式及其所有子项的新解析范围,直到遇到另一个id。

     

请考虑以下摘自您的架构。由于您包含id关键字,因此您的“elementId”和“label”$ref无法按照您的预期解析文档的根,它们会从最近的父架构{{1}解析}。

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 } }, s的模式。我不确定他们认为他们会做出什么好处,但我怀疑他们认为id只是一个标签而不理解它如何改变决议范围。

如果您有充分的理由在任何地方使用id并希望将其保留,您可以在发生冲突时明确引用根id

id