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

如何通过JSON Schema确保JSON数组内对象按指定属性字母序排列?

关于用JSON Schema验证数组对象排序的问题

好问题!先直接给你结论:标准JSON Schema(Draft 2020-12及更早版本)本身不支持直接验证数组元素的排序规则,不过我们可以通过验证库的自定义扩展能力来实现这个需求——主流的JSON Schema验证工具(比如Ajv)都支持添加自定义关键词来实现这类逻辑。

为什么标准JSON Schema做不到?

标准JSON Schema的设计目标是验证数据的结构、类型和单个值的约束,它并不包含用于检查数组元素之间顺序关系的原生关键词。items这类关键词只负责验证数组里的每个元素是否符合指定的结构,完全不关心元素的排列顺序。

实现方案:用自定义关键词扩展验证逻辑

以常用的Ajv库为例,我们可以添加自定义关键词(比如orderedBy),编写自定义验证函数来检查数组是否按照指定属性的升序/降序排列。

步骤1:定义带自定义关键词的JSON Schema

修改你提供的Schema,添加自定义关键词来指定排序规则:

{
  "type": "object",
  "properties": {
    "cities": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "shortName": { "type": "string" },
          "name": { "type": "string" },
          "showInMap": { "type": "boolean" },
          "active": { "type": "boolean" }
        },
        "required": [ "shortName" ]
      },
      // 自定义关键词:指定按shortName升序排列
      "orderedBy": {
        "property": "shortName",
        "order": "asc"
      }
    }
  }
}

步骤2:在Ajv中注册自定义验证逻辑

在Node.js环境下,你可以这样注册自定义关键词并验证数据:

const Ajv = require('ajv');
const ajv = new Ajv();

// 注册自定义关键词"orderedBy"
ajv.addKeyword('orderedBy', {
  type: 'array',
  validate: function(schema, data) {
    const { property, order = 'asc' } = schema;
    // 遍历数组,检查相邻元素的指定属性是否符合排序规则
    for (let i = 0; i < data.length - 1; i++) {
      const current = data[i][property];
      const next = data[i+1][property];
      if (order === 'asc' && current > next) {
        return false;
      }
      if (order === 'desc' && current < next) {
        return false;
      }
    }
    return true;
  },
  // 可选:添加错误信息提示
  errors: true,
  messages: {
    en: "Array must be ordered by {{property}} in {{order}} order"
  }
});

// 加载你的Schema
const schema = require('./your-schema.json');
const validate = ajv.compile(schema);

// 验证有效示例
const validData = {
  "cities": [
    { "shortName": "LD", "name": "London", "showInMap": true, "active": false },
    { "shortName": "MO", "name": "Moscow", "showInMap": false, "active": false },
    { "shortName": "NY", "name": "New York", "showInMap": true, "active": true }
  ]
};
console.log(validate(validData)); // 输出: true

// 验证无效示例
const invalidData = {
  "cities": [
    { "shortName": "NY", "name": "New York", "showInMap": true, "active": true },
    { "shortName": "LD", "name": "London", "showInMap": true, "active": false },
    { "shortName": "MO", "name": "Moscow", "showInMap": false, "active": false }
  ]
};
console.log(validate(invalidData)); // 输出: false
console.log(validate.errors); // 会显示排序错误的提示信息

注意事项

  • 自定义关键词是依赖于具体验证库的,不同的库(比如tv4、Zod)的扩展方式会有所不同,上面的例子仅适用于Ajv。
  • 如果你的使用场景无法依赖第三方库的扩展能力,那可能需要在Schema验证之后,额外添加一层代码逻辑来检查数组的排序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:00:24