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

如何为引用JSON Schema定义的属性添加自定义配置?

JSON Schema引用扩展问题解决方案

为什么你的写法无效

当使用$ref时,JSON Schema会完全采用引用目标的内容,当前对象中与$ref同级的所有属性(比如required、title)都会被忽略,所以你添加的required: ['path']不会生效。

解决方案

根据你的场景(大量引用+多种变体),推荐以下几种方案:

方案1:用allOf组合引用与扩展规则

将$ref放入allOf数组,同时在同级添加差异化配置,两个规则会合并生效:

const schema = {
  $schema: "https://json-schema.org/draft/2020-12/schema",
  type: 'object',
  properties: {
    title:{
      title:"Item title",
      allOf: [
        { $ref:"#/$defs/selector" },
        { required: ['path'] }
      ]
    },
    image:{
      title:"Item image",
      $ref:"#/$defs/selector"
    }
  },
  $defs:{ // 2020-12版本推荐用$defs替代旧的definitions
    selector:{
      type:"object",
      description:"Selectors used to extract datas.",
      properties:{
        path:{
          type:"string",
          title:"Selector path"
        },
        attr:{
          type:"string",
          title:"HTML attribute",
          examples:["src"]
        },
        regex:{
          type:"string",
          title:"Regex pattern",
          format:"regex"
        }
      }
    }
  }
}

方案2:预定义常用变体

如果存在多种重复的变体(比如必填path、必填attr等),可以在$defs中提前定义这些变体,后续直接引用即可,减少重复代码:

const schema = {
  $schema: "https://json-schema.org/draft/2020-12/schema",
  type: 'object',
  properties: {
    title:{
      title:"Item title",
      $ref:"#/$defs/selector-with-required-path"
    },
    image:{
      title:"Item image",
      $ref:"#/$defs/selector"
    },
    content:{
      title:"Content selector",
      $ref:"#/$defs/selector-with-required-attr"
    }
  },
  $defs:{
    selector:{
      type:"object",
      description:"Selectors used to extract datas.",
      properties:{
        path:{
          type:"string",
          title:"Selector path"
        },
        attr:{
          type:"string",
          title:"HTML attribute",
          examples:["src"]
        },
        regex:{
          type:"string",
          title:"Regex pattern",
          format:"regex"
        }
      }
    },
    selector-with-required-path:{
      allOf: [
        { $ref:"#/$defs/selector" },
        { required: ['path'] }
      ]
    },
    selector-with-required-attr:{
      allOf: [
        { $ref:"#/$defs/selector" },
        { required: ['attr'] }
      ]
    }
  }
}

方案3:用动态引用$dynamicRef(2020-12+版本)

如果需要更灵活的动态扩展,JSON Schema 2020-12引入的$dynamicRef和$dynamicAnchor允许直接在引用节点添加属性,无需allOf,会自动合并规则:

const schema = {
  $schema: "https://json-schema.org/draft/2020-12/schema",
  type: 'object',
  properties: {
    title:{
      title:"Item title",
      $dynamicRef:"#/$defs/selector",
      required: ['path']
    },
    image:{
      title:"Item image",
      $dynamicRef:"#/$defs/selector"
    },
    excerpt:{
      title:"Excerpt selector",
      $dynamicRef:"#/$defs/selector",
      properties: {
        regex: { type: "string", minLength: 5 }
      }
    }
  },
  $defs:{
    selector:{
      $dynamicAnchor: "selector", // 标记动态锚点
      type:"object",
      description:"Selectors used to extract datas.",
      properties:{
        path:{
          type:"string",
          title:"Selector path"
        },
        attr:{
          type:"string",
          title:"HTML attribute",
          examples:["src"]
        },
        regex:{
          type:"string",
          title:"Regex pattern",
          format:"regex"
        }
      }
    }
  }
}

总结

  • 直接在$ref同级加属性无效,因为$ref会完全替换当前节点内容
  • 少量差异化用allOf组合;固定变体多就预定义;需要高度灵活的动态扩展用$dynamicRef(注意版本兼容)

内容的提问来源于stack exchange,提问作者gordie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:20:26