如何保留JSON Schema中的$id同时避免$ref失效?
问题
在Python中使用jsonref库调用jsonschema.validate验证下方JSON Schema时,second_definition里的$id字段会触发jsonschema.exceptions._WrappedReferencingError错误,错误提示包含referencing.exceptions.PointerToNowhere,指向#/definitions/first_definition的$ref失效。删除$id能解决问题,但希望保留$id的同时修复该问题。
目标验证的Schema:
{ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "first_definition": { "value": "this is definitions/first_definition" }, "second_definition": { "$id": "any_value", "properties": { "sections": { "$ref": "#/definitions/first_definition" } } } }, "$ref": "#/definitions/second_definition" }
问题原因
$id的作用是为所在的子Schema创建一个独立的URI作用域,此时子Schema内的#/definitions/first_definition是相对于这个子Schema本身的,而子Schema里并没有definitions节点,自然找不到目标定义,导致报错。
解决方法
方法1:给根Schema加$id,用绝对URI引用
给根Schema指定一个基准$id,然后在子Schema的$ref里用完整的绝对URI指向根的definitions:
修改后的Schema:
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://example.com/root_schema", "definitions": { "first_definition": { "value": "this is definitions/first_definition" }, "second_definition": { "$id": "any_value", "properties": { "sections": { "$ref": "https://example.com/root_schema#/definitions/first_definition" } } } }, "$ref": "#/definitions/second_definition" }
方法2:用相对URI引用根定义
如果不想给根Schema加$id,可以利用URI相对路径,从子Schema的$id回到根层级再引用definitions:
修改后的Schema:
{ "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "first_definition": { "value": "this is definitions/first_definition" }, "second_definition": { "$id": "any_value", "properties": { "sections": { "$ref": "../#/definitions/first_definition" } } } }, "$ref": "#/definitions/second_definition" }
方法3:用$anchor替代$id(需Schema版本支持)
如果$id只是用来标识子Schema,不需要独立作用域,可以改用$anchor(JSON Schema Draft 2019-09及以后版本支持),这样既保留标识功能,又不会改变$ref的作用域:
修改后的Schema:
{ "$schema": "https://json-schema.org/draft/2019-09/schema#", "definitions": { "first_definition": { "value": "this is definitions/first_definition" }, "second_definition": { "$anchor": "any_value", "properties": { "sections": { "$ref": "#/definitions/first_definition" } } } }, "$ref": "#/definitions/second_definition" }
内容的提问来源于stack exchange,提问作者Max Kessler
相关产品推荐
相关产品推荐

