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

如何基于外部JSON文件有效值验证Region JSON Schema的Country属性

好的,我来帮你解决这个问题——你想要定义region的JSON Schema,让其中的countries属性自动关联countries.json里的国家code,又不想手动重复枚举列表对吧?这里有两种靠谱的方案,你可以根据自己的场景选择:

方案1:动态生成可复用的枚举Schema(推荐,兼容性强)

JSON Schema本身没办法直接读取外部JSON实例(比如countries.json)的值来做验证,但我们可以用脚本动态生成一个包含国家code枚举的Schema片段,然后在country和region的Schema里都引用它,这样就不用手动维护重复的列表了。

步骤1:写脚本生成枚举Schema

用Node.js写个简单的脚本(其他语言也可以,逻辑一样),读取countries.json并提取所有code值,生成一个独立的枚举Schema文件:

const fs = require('fs');

// 读取countries.json里的国家列表
const countries = JSON.parse(fs.readFileSync('./countries.json', 'utf8'));
// 提取所有国家code
const countryCodes = countries.map(country => country.code);

// 生成枚举Schema
const enumSchema = {
  "$id": "https://example.com/country-codes-enum.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "string",
  "enum": countryCodes
};

// 写入文件
fs.writeFileSync('./country-codes-enum.schema.json', JSON.stringify(enumSchema, null, 2));

步骤2:重构原有的Country Schema

把原来的country数组Schema改成引用这个枚举片段,确保国家code的验证和region的验证用的是同一套规则:

{
  "$id": "https://example.com/countries.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "A list of countries",
  "type": "array",
  "items": {
    "type": "object",
    "required": ["code", "name"],
    "properties": {
      "code": { "$ref": "country-codes-enum.schema.json" },
      "name": { "type": "string" }
    }
  }
}

步骤3:定义Region Schema

现在region的Schema就可以直接引用这个枚举片段来验证countries数组的元素了,完全不用手动写枚举:

{
  "$id": "https://example.com/regions.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "A list of regions",
  "type": "array",
  "items": {
    "type": "object",
    "required": ["name", "countries"],
    "properties": {
      "name": { "type": "string" },
      "countries": {
        "type": "array",
        "items": { "$ref": "country-codes-enum.schema.json" },
        "uniqueItems": true // 可选:防止同一个region里重复添加同一个国家code
      }
    }
  }
}

以后只要countries.json更新了,重新跑一遍脚本生成新的枚举Schema就行,两个主Schema都会自动用上最新的国家列表。


方案2:用支持$data关键字的验证器(比如Ajv)

如果你的验证工具支持JSON Schema Draft 07的$data关键字(比如Ajv这个常用的JS验证库),可以直接在Region Schema里引用countries.json的实例数据,不用额外生成枚举文件。

步骤1:定义Region Schema

直接用$data指向countries.json里的code值路径(路径语法要对应验证器的规则):

{
  "$id": "https://example.com/regions.schema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "A list of regions",
  "type": "array",
  "items": {
    "type": "object",
    "required": ["name", "countries"],
    "properties": {
      "name": { "type": "string" },
      "countries": {
        "type": "array",
        "items": {
          "type": "string",
          "minLength": 2,
          "maxLength": 2,
          "$data": "1/countries/*/code" // 路径对应验证上下文里的countries数据结构
        },
        "uniqueItems": true
      }
    }
  }
}

步骤2:用Ajv验证时传入上下文数据

在验证region数据的时候,把countries.json的数据作为上下文传入Ajv:

const Ajv = require('ajv');
const ajv = new Ajv({ $data: true }); // 一定要启用$data支持
const fs = require('fs');

// 加载Schema和数据
const regionSchema = JSON.parse(fs.readFileSync('./regions.schema.json', 'utf8'));
const countriesData = JSON.parse(fs.readFileSync('./countries.json', 'utf8'));
const regionData = [
  { "name": "Europe", "countries": ["GB"] },
  { "name": "North America", "countries": ["US"] }
];

// 编译验证函数并验证
const validate = ajv.compile(regionSchema);
const isValid = validate(regionData, { countries: countriesData });

if (!isValid) {
  console.error('验证失败:', validate.errors);
} else {
  console.log('验证通过!');
}

这种方法不用生成额外文件,但依赖验证器对$data的支持,兼容性不如方案1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:24:04