Python jsonschema 无法验证 JSON 模式条件嵌套属性

Python jsonschema unable to validate JSON schema conditional nested properties

重新发布问题 How to implement conditional nested properties with JSON Schema(标记为重复,尽管它是一个完全不同的问题) 我的 JSON 架构如下所示,尝试基于:

{
  "$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。寻找一些指导,如何解决这个问题。

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

首先,让我们评估一下我们的假设是否正确...看起来 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 模式值,并将其用作整个模式。这样您就可以找出验证失败的原因,而不仅仅是猜测。

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