如何基于另一个属性中的枚举值执行JSON架构属性验证



基于给定的JSON架构,如果我必须根据DayHeader中选择的"Day"为"DayActivity"构建"required"(例如,如果Day是SUNDAY,则只需要PhysicalActivity(,我如何构建JSON架构?我尝试过各种方法,比如if-then-else和定义。当我基于JSON模式生成JSON文件时,它无法验证"Day"属性所选的必需"DayActivity"。基本上,我如何引用在其他属性中选择的值并构建"必需"?感谢对本期的任何参考。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "DayHeader": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "Day": {
          "type": "string",
          "enum": [
            "SUNDAY",
            "MONDAY",
            "TUESDAY",
            "WEDNESDAY",
            "THURSDAY",
            "FRIDAY",
            "SATURDAY"
          ]
        }
      },
      "required": [
        "day"
      ]
    },
    "ActivityDetail": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "DayActivity": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "PhysicalActivity": {
                "type": "string",
                "enum": [
                  "Walking",
                  "Running"
                ]
              },
              "StudyActivity": {
                "type": "string",
                "enum": [
                  "Maths Class",
                  "Science Class"
                ]
              },
              "ArtActivity": {
                "type": "string",
                "enum": [
                  "Drawing",
                  "Dance"
                ]
              }
            }
          }
        }
      }
    }
  }
}

一般来说,这个问题在这里已经有了一个很棒的通用答案。

话虽如此,您可能能够改进关于"DayActivity"的数据结构,这也将使制定相应的JSON模式变得更容易。


您的"DayActivity"当前是一个对象数组,每个对象最多同时包含三个属性:"PhysicalActivity"/"StudyActivity"/"ArtActivity"。不如用下面的方法,只允许三个属性中的一个出现在单个数组项中:

"DayActivity": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"oneOf": [
{
"properties": {
"PhysicalActivity": {
"type": "string",
"enum": ["Walking", "Running"]
}
},
"required": ["PhysicalActivity"]
},
{
"properties": {
"StudyActivity": {
"type": "string",
"enum": ["Maths Class", "Science Class"]
}
},
"required": ["StudyActivity"]
},
{
"properties": {
"ArtActivity": {
"type": "string",
"enum": ["Drawing", "Dance"]
}
},
"required": ["ArtActivity"]
}
]
},
"contains": {
"required": ["PhysicalActivity"]
}
}

请注意最后的"contains"关键字,以确保"DayActivity"数组中始终需要至少有一个"PhysicalActivity"条目。

如果您现在希望在除"SUNDAY"之外的每个工作日有条件地强制执行"StudyActivity",则可以在主模式中添加以下内容(即在声明"properties": { "DayHeader": ... }的顶层:

"oneOf": [
{
"properties": {
"DayHeader": {
"properties": {
"Day": {
"const": "SUNDAY"
}
}
}
}
},
{
"properties": {
"DayHeader": {
"properties": {
"Day": {
"enum": [
"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"
]
}
}
},
"ActivityDetail": {
"properties": {
"DayActivity": {
"contains": {
"required": ["StudyActivity"]
}
}
}
}
}
}
]

一个完整的模式可能看起来像这样:

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["DayHeader", "ActivityDetail"],
"properties": {
"DayHeader": {
"type": "object",
"properties": {
"Day": {
"type": "string",
"enum": [
"SUNDAY",
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY"
]
}
},
"required": [
"Day"
]
},
"ActivityDetail": {
"type": "object",
"required": ["DayActivity"],
"properties": {
"DayActivity": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"oneOf": [
{
"properties": {
"PhysicalActivity": {
"type": "string",
"enum": ["Walking", "Running"]
}
},
"required": ["PhysicalActivity"]
},
{
"properties": {
"StudyActivity": {
"type": "string",
"enum": ["Maths Class", "Science Class"]
}
},
"required": ["StudyActivity"]
},
{
"properties": {
"ArtActivity": {
"type": "string",
"enum": ["Drawing", "Dance"]
}
},
"required": ["ArtActivity"]
}
]
},
"contains": {
"required": ["PhysicalActivity"]
}
}
}
}
},
"oneOf": [
{
"properties": {
"DayHeader": {
"properties": {
"Day": {
"const": "SUNDAY"
}
}
}
}
},
{
"properties": {
"DayHeader": {
"properties": {
"Day": {
"enum": [
"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"
]
}
}
},
"ActivityDetail": {
"properties": {
"DayActivity": {
"contains": {
"required": ["StudyActivity"]
}
}
}
}
}
}
]
}

以上成功验证:

{
"DayHeader": { "Day": "SUNDAY"},
"ActivityDetail": {
"DayActivity": [
{ "PhysicalActivity": "Walking" }
]
}
}

但不反对以下情况(因为缺少"StudyActivity"

{
"DayHeader": { "Day": "WEDNESDAY"},
"ActivityDetail": {
"DayActivity": [
{ "PhysicalActivity": "Walking" }
]
}
}