问题描述
重新发布问题How to implement conditional nested properties with JSON Schema(标记为重复,但它是一个完全不同的问题) 我的 JSON 架构读取如下基于:JSON Schema if/then require nested object
{
"$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","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','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","pattern": "^(.*.)(exe)$"
}
}
}
}
此外,另一个模式调试技巧是取出 if
模式值,并将其用作整个模式。这样您就可以找出验证失败的原因,而不仅仅是猜测。
这些是很容易犯的错误!我在尝试修复它时做了一些。重要的是要知道如何调试您的架构。测试假设,并识别子模式。