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

如何使用Ajv验证包含不同嵌套$schema值的数据?

问题分析与解决方案

核心问题

Ajv 默认不会识别数据中的$schema字段来自动切换验证使用的 schema。你当前代码里的anyOf逻辑只是让foo匹配intSchema或strSchema中的任意一个,所以dataB里的value:1因为符合intSchema的规则,导致anyOf条件满足,最终返回true——这和数据里的$schema字段完全无关,因为对Ajv来说,这个字段只是普通的对象属性。

解决方案:用$data关键字实现动态schema引用

Ajv 支持通过$data关键字(需手动启用)引用数据字段的值,以此动态选择要使用的验证schema。

修改后的代码示例

const ajv = new Ajv({ $data: true }); // 启用$data关键字支持

const mainSchema = {
  $id: "mainSchema",
  type: "object",
  properties: {
    foo: {
      // 引用当前foo对象的$schema字段值对应的schema
      $ref: { $data: "0/$schema" }
    },
  },
};
const intSchema = {
  $id: "intSchema",
  type: "object",
  properties: {
    value: { type: "integer" },
    // 可选:强制数据中的$schema值必须与当前schema的$id匹配
    $schema: { const: "intSchema" }
  },
  required: ["value"]
};
const strSchema = {
  $id: "strSchema",
  type: "object",
  properties: {
    value: { type: "string" },
    $schema: { const: "strSchema" }
  },
  required: ["value"]
};

const dataA = {
  $schema: "mainSchema",
  foo: {
    $schema: "intSchema",
    value: 42,
  },
};

const dataB = {
  $schema: "mainSchema",
  foo: {
    $schema: "strSchema",
    value: 1,
  },
};

const dataC = {
  $schema: "mainSchema",
  foo: {
    $schema: "unknownSchema",
    value: false,
  },
};

ajv.addSchema([intSchema, strSchema]);
const validate = ajv.compile(mainSchema);
console.log(validate(dataA)); // true
console.log(validate(dataB)); // false(符合预期)
console.log(validate(dataC)); // false

代码说明

  1. 启用$data选项:创建Ajv实例时传入{ $data: true },开启数据字段引用功能。
  2. 动态引用schema:$ref: { $data: "0/$schema" }表示取当前foo对象的$schema字段值,作为要引用的schema的$id,实现根据数据指定的schema进行验证。
  3. 可选的字段一致性校验:在子schema中添加$schema: { const: "xxxSchema" },可以确保数据里的$schema值和当前验证的schema严格匹配,避免出现“数据指定了strSchema但实际符合intSchema”的混淆情况。

备选方案:手动遍历数据验证

如果你不想依赖$data关键字,也可以手动遍历数据对象,提取每个嵌套对象的$schema字段值,从Ajv实例中获取对应的schema进行单独验证。这种方式更繁琐,但适合复杂的自定义场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 07:35:36