JSON 使用不同的 属性 名称验证 JSON 的架构

JSON Schema validating JSON with different property names

我正在使用 JSON Schema Draft 4,遇到一个我无法完全理解的问题。在下面的架构中,您将看到一个数组 metricsGroups,其中任何项目都应恰好 oneOf 定义的子架构。在子模式中,您会注意到它们都共享 属性 名称 timestamp,但是 metricsGroupOne 具有属性 temperaturehumiditymetricsGroupTwo 具有属性 PIRCO2metricsGroups 中的所有属性都是必需的。

请参阅下面的架构。架构下方是一些我希望得到验证但被视为无效的数据示例以及对我的问题的解释。

{
  "type": "object",
  "properties": {
    "uniqueId": {
      "type": "string"
    },
    "metricsGroups": {
      "type": "array",
      "minItems": 1,
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "metricsGroupOne": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "object",
                  "properties": {
                    "timestamp": {
                     "type": "string",
                      "format": "date-time"
                    },
                    "temperature": {
                      "type": "number"
                    },
                    "humidity": {
                      "type": "array",
                     "items": {
                        "type": "number"
                      }
                    }
                  },
                  "additionalProperties": false,
                  "required": [
                    "timestamp",
                    "temperature",
                    "humidity"
                  ]
                }
              }
            },
            "required": [
              "metricsGroupOne"
            ]
          },
          {
            "type": "object",
            "properties": {
              "metricsGroupTwo": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "object",
                  "properties": {
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "PIR": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    },
                    "CO2": {
                      "type": "number"
                    }
                  },
                  "additionalProperties": false,
                  "required": [
                    "timestamp",
                    "PIR",
                    "CO2"
                  ]
                }
              }
            },
            "required": [
              "metricsGroupTwo"
            ]
          }
        ]
      }
    }
  },
  "additionalProperties": false,
  "required": [
    "uniqueId",
    "metricsGroups"
  ]
}

以下是我认为应该有效的一些数据:

{
  "uniqueId": "d3-52-f8-a1-89-ee",
  "metricsGroups": [
    {
      "metricsGroupOne": [
        {"timestamp": "2020-03-04T12:34:00Z", "temperature": 32.5, "humidity": [45.0] }
      ],
      "metricsGroupTwo": [
        {"timestamp": "2020-03-04T12:34:00Z", "PIR": [16, 20, 7], "CO2": 653.76 }
      ]
    }
  ]
}

我面临的问题是,我认为是有效数据的两个 metricsGroup 数组都针对两个子模式进行了验证 - 由于使用 oneOf 关键字。我不明白 metricsGroupOne 的条目如何根据 metricsGroupTwo 的架构进行验证,因为 属性 名称不同,反之亦然。

我在幕后使用了一个节点库来抛出这个错误,但我也测试过在一些在线验证测试网站上也会出现同样的错误:

感谢任何帮助。谢谢, 亚当

JSON 架构使用基于约束的方法。如果你不定义某些东西是不允许的,它是允许的。

这里发生的事情是,您没有在 oneOf[1] 中指定任何会使实例数据数组中的第一项无效的内容。

让我用一个简单的例子来说明这一点。

我的架构。我打算使用 draft-07,但是 draft-04

这个原则没有区别
{
  "oneOf": [
    {
      "properties": {
        "a": true
      }
    },
    {
      "properties": {
        "b": false
      }
    }
  ]
}

我的实例:

{
  "a": 1
}

验证失败,因为在应用两个 oneOf 模式时实例有效。

演示:https://jsonschema.dev/s/EfUc4

如果实例是代替...

{
  "a": 1,
  "b": 1
}

这将是有效的,因为实例未通过子模式验证 oneOf[1]

如果实例是...

{
  "b": 1
}

根据 oneOf[0] 有效,但根据 oneOf[1] 无效,因此总体上有效,因为它仅根据一个子模式有效。

在您的情况下,您可能需要使用 additionalProperties 来禁止未在 properties 中定义的属性。我无法从你的问题中判断你是否想要允许这两个属性,因为你的模式被定义为 oneOf 这似乎与你期望有效的实例冲突。