You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建可在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:33:17