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

JSON Schema中基于日期动态设置maxItems的问题排查与修正

问题原因

JSON Schema Draft-07不支持基于实例数据动态计算验证参数——你无法从period.label的yyyy_mm格式值中解析出年月、计算天数后再设置days.maxItems。你之前的写法要么错误尝试了非标准的动态引用(比如Draft-07未纳入规范的$data关键字,多数验证工具不支持),要么条件判断逻辑失效,导致所有数据都能通过验证。

修正方案

根据需求,有两种可行方案:

方案1:升级到JSON Schema Draft 2020-12(推荐)

Draft 2020-12支持更灵活的条件判断,结合正则匹配年月模式,可实现精准的动态验证。以下是完整Schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "period": {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "pattern": "^\\d{4}_\\d{2}$"
        }
      },
      "required": ["label"]
    },
    "days": {
      "type": "array"
    }
  },
  "required": ["period", "days"],
  "allOf": [
    // 匹配闰年2月(29天):能被400整除,或能被4整除但不能被100整除的年份
    {
      "if": {
        "properties": {
          "period": {
            "properties": {
              "label": {
                "pattern": "^((\\d{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)_02)$"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "days": {
            "maxItems": 29
          }
        }
      }
    },
    // 匹配非闰年2月(28天)
    {
      "if": {
        "properties": {
          "period": {
            "properties": {
              "label": {
                "pattern": "^((\\d{2}(0[1235679]|[13579][13579]|[2468][026])|(0[13579]|[13579][13579]|[2468][026])00)_02)$"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "days": {
            "maxItems": 28
          }
        }
      }
    },
    // 匹配31天的月份:1、3、5、7、8、10、12月
    {
      "if": {
        "properties": {
          "period": {
            "properties": {
              "label": {
                "pattern": "^\\d{4}_(0[13578]|1[02])$"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "days": {
            "maxItems": 31
          }
        }
      }
    },
    // 匹配30天的月份:4、6、9、11月
    {
      "if": {
        "properties": {
          "period": {
            "properties": {
              "label": {
                "pattern": "^\\d{4}_(0[469]|11)$"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "days": {
            "maxItems": 30
          }
        }
      }
    }
  ]
}

这个Schema通过allOf组合4组if/then规则,用正则匹配不同年月模式,对应设置days数组的最大长度。测试时,2024_02(闰年2月)的days数组超过29个元素就会验证失败,符合预期。

方案2:继续使用Draft-07(枚举所有可能规则)

Draft-07支持if/then/allOf,但无法动态计算,只能枚举所有年月的匹配规则。写法和上面的Schema基本一致,只需将$schema字段改为Draft-07的地址:

"$schema": "http://json-schema.org/draft-07/schema#"

注意:如果年月范围很大,枚举规则会非常冗长,因此优先推荐方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:35:15