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

JSON Schema:能否将displayName默认值设为父级键及引用enum到required?

JSON Schema 核心问题求解

一、动态默认值:将displayName默认值设为父对象属性键

我有一个包含$defs的JSON Schema,用于验证类似"machines":{"FA23":{...}}的结构。$defs内定义了machine对象,其中displayName属性希望默认值自动匹配对应的机器键(如FA23),且我不想通过程序化方式生成Schema。

需求背景

  • 避免单独维护存储默认值的额外结构,希望验证通过后直接解析Schema填充缺失的默认值
  • 解析函数需具备通用性,可跨项目复用,因此默认值必须是确切值,或无需特定Schema逻辑的安全获取方式
  • 当前使用draft-07版本,但不绑定特定版本;运行环境为Node.js v14(Node-RED),尽量避免使用额外模块或代码生成Schema
  • 采用对象属性列表而非数组,因为这是运行时实际使用的结构,可直接写入文件无需转换

当前Schema子集

{
    "$schema":"http://json-schema.org/draft-07/schema#",
    "title":"commonConfigSchema",
    "description":"global common config for this project",
    "$defs":{
        "javascriptFalsy":{
            "enum":[false, 0, null, ""]
        },
        "macKey":{
            "type":"string",
            "enum":["FA419","FA420","FA421","FA422","FA423","MO41","MO42","OMET"]
        },
        "signalKey":{
            "type":"string",
            "enum":["noop","A1","A2","A3","A4","B","C1","C2","D","E"],
            "default":"noop"
        },
        "towerDevice":{
            "type":"string",
            "enum":["redLight","greenLight","horn"]
        },
        "machine":{
            "type":"object",
            "properties":{
                "displayName":{"type":"string", "default":"this.parent.key"},
                "cellHeaderText":{"type":"string", "default":"Linea + this.displayName"},
                "toA3Timeout":{"type":"integer", "minimum":0, "default":20000},
                "toA4Timeout":{"type":"integer", "minimum":0, "default":"120*60*1000"},
                "initCellSignalKey":{"$ref":"#/$defs/signalKey", "default":"noop"},
                "initTowerBits":{
                    "type":"object",
                    "propertyNames":{"$ref":"#/$defs/towerDevice"},
                    "patternProperties":{".":{"enum":[0, 1, true, false], "default":0}}
                }
            },
            "$comment":"exactly all the props are required",
            "additionalProperties":false,
            "required":["displayName", "cellHeaderText", "toA3Timeout", "toA4Timeout", "initCellSignalKey", "initTowerBits"]
        }
    },
    "type":"object",
    "properties":{
        "machines":{
            "$description": "holding machine-specific configs. Made up of macKey:config pairs",
            "type":"object",
            "propertyNames":{"$ref":"#/$defs/macKey"},
            "patternProperties":{".":{"$ref":"#/$defs/machine"} },
            //"required":{"$ref":"#/$defs/macKey/enum"},
            "required":["FA419","FA420","FA421","FA422","FA423","MO41","MO42","OMET"],
            "additionalProperties":false
        }
    },
    "required":["cellsLayout", "machines"],
    "additionalProperties":false
}

我尝试在displayName的default字段中写入"this.parent.key",但这并非标准JSON Schema支持的语法,想了解有没有标准方式实现该需求?


二、能否引用enum数组作为required属性值

我尝试将machines的required数组绑定到macKey的enum定义,避免重复维护两份相同的键列表,但之前了解到$ref指向的是Schema而非字符串数组,旧回答称此方式不可行,想知道现在(包括后续draft版本)是否有变化?


问题解答

关于动态默认值

JSON Schema的default关键字仅支持静态值,不支持引用父对象属性键这类动态逻辑。可通过以下方式满足需求:

  • 自定义通用解析逻辑:验证完成后,遍历machines对象的键值对,若displayName缺失,直接将当前键赋值给它。可给displayName添加$comment标记(如"$comment": "default-to-parent-key"),让解析函数识别并处理,这种方式无需修改Schema核心结构,且解析逻辑可跨项目复用。
  • 即使升级到draft-2020-12版本,仍无法直接实现动态默认值,核心的动态赋值逻辑仍需在解析层处理。
  • 不要在default中写入表达式,这不属于标准语法,没有通用解析器会识别。

关于引用enum作为required数组

截至目前(包括最新的draft-2020-12),JSON Schema仍然不支持直接引用另一个Schema的enum数组作为required的值。$ref只能指向完整的Schema节点,无法提取其中的enum数组内容。

避免冗余的可行方式:

  • 程序化生成Schema:编写简单脚本,从macKey的enum数组中提取值生成machines的required数组,后续仅需维护macKey的enum即可,一次性生成后无需重复执行。
  • 使用JSON Schema预处理器:如自定义扩展json-schema-ref-parser这类工具实现引用逻辑,但需要引入额外模块,可能不符合你的环境要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:25:03