【问题标题】:Can a JSON schema specify required properties in object OR array?JSON 模式可以在对象或数组中指定所需的属性吗?
【发布时间】:2021-08-31 20:25:37
【问题描述】:

我很难理解是否可以编写需要某些属性的 json 模式,但也允许这些属性位于 json 文件的不同区域(例如,属性值可以位于主顶级对象中或它可以在一个数组中——它只需要在某个地方)。

例如,我有一些设备会在几个小时内收集多个温度记录并分批发送记录。但是,有些设备会在主对象中发送一次软件版本,而其他设备会随每个小时的温度记录一起发送软件版本(在“records”数组中)。

示例 1(swversion 在主对象中发送一次):

{
    "name": "device1",
    "swversion": "1.3.abc2",
    "records": [
        {
            "time": "10am",
            "temp": 2
        },
        {
            "time": "11am",
            "temp": 4
        }
    ]
}

示例 2(swversion 在“记录”数组中发送):

{
    "name": "device1",
    "records": [
        {
            "time": "10am",
            "temp": 2,
            "swversion": "1.3.abc2"
        },
        {
            "time": "11am",
            "temp": 4,
            "swversion": "1.3.abc2"
        }
    ]
}

使用这些示例,我想将我的架构定义编写如下(前两个项目符号很简单,最后一个项目符号是我苦苦挣扎的地方):

  • 主对象需要name 属性和records 数组
  • records 数组可以包含需要 time 和 temp 的对象
  • swversion 是必需的某处(可以在主对象中或在records 数组中)

我在 json-schema 中是否缺少一个强制必需属性的功能,但允许所述属性的灵活性任何地方(例如,在对象或数组中),只要他们在某处吗?

【问题讨论】:

    标签: json jsonschema json-schema-validator


    【解决方案1】:

    anyOf 关键字是布尔或运算。必须至少有一个模式通过才能使关键字通过。第一个模式要求“swversion”属性出现在顶层。第二种模式要求“记录”数组中的每个项目都需要“swversion”属性。

    {
      ... define the easy stuff here, then ...,
    
      "anyOf": [
        { "required": ["swversion"] },
        {
          "properties": {
            "records": {
              { "items": { "required": ["swversion"] } }
            }
          }
        }
      ]
    }
    

    在本例中,“swversion”可能出现在两个位置。如果您只想确保它只出现在一个地方(顶级或项目),您可以使用oneOf 而不是anyOf。

    【讨论】:

      【解决方案2】:

      是否有一个功能..允许所述属性在任何地方的灵活性

      不直接,但表达这一点并不难。您可以在定义中定义“swversion”本身的结构,并通过引用重复使用。

      在伪代码中,应该是:

      任何一个:

      • 主对象包含一个“swversion”属性,
      • “记录”下的所有项目都包含“swversion”属性

      在代码中:

      {
        "$defs": {
          "swversion": {
            "type": "string",
            .. other constraints?
          }
        },
        "type": "object",
        "properties": {
          ... other property definitions ...,
          "records": {
            "items": {
               "type": "object",
               ... other definitions for the mandatory portion of records ...
            }
          }
        },
        "anyOf": [
          {
            "$comment": "swversion is a member of the main object",
            "required": [ "swversion" ],
            "properties": {
              "swversion": {
                "$ref": "#/$defs/swversion"
             }
          },
          {
            "$comment": "swversion is a member of all the items under the records property",
            "properties": {
              "records": {
                "items": {
                  "type": "object",
                  "required": [ "swversion" ],
                  "properties": {
                    "swversion": {
                      "$ref": "#/$defs/swversion"
                   }
                 }
               }
              }
            }
          }
        ],
      }
      

      请注意,如果您使用的是 JSON Schema 版本 Draft7 或更早版本,请将 $defs 更改为 definitions。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-12
        • 1970-01-01
        • 2016-11-07
        • 2021-04-17
        • 1970-01-01
        • 2013-05-02
        相关资源
        最近更新 更多