如何创建可在JSON Schema任意位置使用的自定义关键字
解决JSON Schema自定义关键字嵌套时元Schema验证失效的问题
核心问题定位
你碰到的问题本质是自定义词汇表未被正确关联到所有嵌套子Schema。jschon默认仅对顶层Schema应用指定词汇表,嵌套在properties这类字段下的子Schema如果没有显式继承词汇表配置,就不会触发自定义关键字的元校验规则。
具体修复步骤
1. 让元Schema明确关联自定义词汇表
修改meta.schema.json,通过$vocabulary关键字声明自定义词汇表的URI,确保所有子Schema都会继承该词汇表:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/meta-schema", "$vocabulary": { "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/applicator": true, "https://example.com/custom-vocab": true // 自定义词汇表的URI }, "allOf": [ {"$ref": "https://json-schema.org/draft/2020-12/schema"}, {"$ref": "vocab.schema.json"} ] }
2. 让词汇表规则递归覆盖所有子Schema
调整vocab.schema.json,通过动态锚点和引用,让自定义关键字的元规则作用于所有层级的Schema:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/custom-vocab", "type": "object", "properties": { "myKeyword": { "type": "object" // 自定义关键字的格式校验规则 } }, "additionalProperties": true, "$dynamicAnchor": "meta", // 设置动态锚点,供子Schema继承 "$dynamicRef": "#meta" // 递归引用锚点,将规则应用到所有嵌套子Schema }
3. 在jschon中正确初始化词汇表与元Schema
修改test.py,确保自定义词汇表被注册到环境,且所有待校验的Schema(包括嵌套子Schema)都关联你的自定义元Schema:
from jschon import create_catalog, JSONSchema, URI # 初始化catalog并注册自定义词汇表 catalog = create_catalog('2020-12') catalog.add_vocabulary( URI("https://example.com/custom-vocab"), catalog.load_schema(URI("vocab.schema.json")) ) # 加载自定义元Schema meta_schema = catalog.load_schema(URI("https://example.com/meta-schema")) # 测试嵌套场景:验证包含错误格式关键字的子Schema test_schema = JSONSchema({ "type": "object", "properties": { "foo": { "myKeyword": "not an object" // 此处违反myKeyword必须为对象的规则 } } }, metaschema=meta_schema) # 执行元校验,验证Schema本身的合法性 result = meta_schema.evaluate(test_schema) print(result.valid) // 应返回False,触发格式错误校验
关键原理说明
- jschon的元校验仅在Schema明确关联包含自定义词汇表的元Schema时触发,嵌套子Schema不会自动继承顶层配置,必须通过
$dynamicAnchor和$dynamicRef实现规则的递归传递。 - 自定义元Schema必须通过
$vocabulary声明所有依赖的词汇表(包括核心词汇表和自定义词汇表),这样properties这类applicator关键字才能将词汇表规则传递给子Schema。
内容的提问来源于stack exchange,提问作者Sahil Patel
相关产品推荐
相关产品推荐

