1

重新发布问题如何使用 JSON Schema 实现条件嵌套属性(标记为重复,尽管它是一个完全不同的问题)我的 JSON 模式在下面尝试基于:JSON Schema if/then 需要嵌套对象

{
  "$id": "myschema.json",
  "if":{
    "type":"object",
    "properties": {
      "common_data": {
        "type":"object",
        "properties":{
          "remote_os": {
              "type":"object",
              "required":["common_data"],
              "const": "Linux"
            }
          },
          "required":["remote_os"]
      }
    }
  },
  "then": {
    "type":"object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(bin)$"
        }
      }
  },
  "else": {
    "type":"object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(exe)$"
        }
      }
  }
}

基本上添加if-else逻辑以确保remote_os=Linux file应该结束.bin并且remote_os=Windows file应该结束.exe 现在我正在尝试验证以下数据

{
  "common_data": {
    "remote_os": "Linux"
  },
  "file": "abc.bin"
}

得到错误:[<ValidationError: "'abc.bin' does not match '^(.*.)(exe)$'">]

当尝试调试python jsonschema尝试在此架构之上构建的属性以验证我的数据时。收到

properties {'common_data': {'type': 'object', 'properties': {'remote_os': {'type': 'object', 'required': ['common_data'], 'const': 'Linux'}}, 'required': ['remote_os']}}
properties {'remote_os': {'type': 'object', 'required': ['common_data'], 'const': 'Linux'}}
properties {'file': {'type': 'string', 'pattern': '^(.*.)(exe)$'}}

'pattern': '^(.*.)(exe)$'所以它总是与不考虑的匹配remote_os。寻找一些指导,如何解决这个问题。

4

1 回答 1

0

你很接近,但有一些问题。

首先,让我们评估一下我们的假设是否正确……看起来if失败了,并触发了else要应用的架构值而不是then架构值。我们可以通过if简单地更改来检查这一点true

是的,then子模式在应用时可以正常工作。

好的,所以让我们删除嵌套模式的一部分,直到它按我们预期的那样工作......

啊……看。remote_os在我们的数据中是一个字符串,但它已在模式中定义为一个对象。删除type: object.

那些required关键字与数据位置不匹配......它们只需要向上移动到正确的级别......

我们最终得到了这个模式:(现场演示:https ://jsonschema.dev/s/CEwMw )

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "myschema.json",
  "if": {
    "type": "object",
    "required": [
      "common_data"
    ],
    "properties": {
      "common_data": {
        "type": "object",
        "required": [
          "remote_os"
        ],
        "properties": {
          "remote_os": {
            "const": "Linux"
          }
        }
      }
    }
  },
  "then": {
    "type": "object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(bin)$"
      }
    }
  },
  "else": {
    "type": "object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(exe)$"
      }
    }
  }
}

此外,另一个模式调试技巧是取出if模式值,并将其用作整个模式。这样您就可以找出验证失败的原因,而不仅仅是猜测。

这些都是容易犯的错误!我在尝试修复它时做了一些。重要的是要知道如何调试您的架构。测试假设,并识别子模式。

于 2021-05-07T09:18:48.633 回答