JSON if/then/else 属性 的架构 属性 可以是对象或基于另一个属性值的 null

JSON Schema if/then/else for property that can be an object or null based on another properties value

我有一个 属性,它将是一个对象或基于另一个 属性 的值的 null。我正在尝试使用 if/then/else 将这个新检查添加到我的架构中。如果相关的话,这是为了在 Postman 中进行 AJV 验证。

例如,这个示例负载

{
  "topObj": {
    "subItem1": "2021-09-12",
    "subItem2": "2021-09-21",
    "ineligibleReason": "",
    "myObject": {
      "subObject1": true,
      "subObject2": ""
    }
  }
}

如果 ineligibleReason 是一个空字符串,那么 subObject 应该是一个对象。如果 ineligibleReason 不是空字符串,则 subObject 应该为空,如 table:

ineligibleReason value myObject value schema valid?
"" object true
"" null false
"any value" null true
"any value" object false

这是我目前所拥有的。 jsonschema.dev 认为它是一个有效的模式,但是当我在有效负载中向 ineligibleReason 添加一个值时(将 myObject 保留为一个对象)它仍然说 JSON 有效负载有效!

{
  "type": "object",
  "properties": {
    "topObj": {
      "type": "object",
      "properties": {
        "subItem1":         { "type": "string" },
        "subItem2":         { "type": "string" },
        "ineligibleReason": { "type": "string" },
        "myObject":         { "type": ["object", "null"] }
      }
    }
  },
  "required": ["topObj"],
  "additionalProperties": false,
  
  "if": {
    "properties": { "topObj.ineligibleReason": { "const": "" } }
  },
  "then": {
    "properties": { 
      "topObj.myObject": {
        "type": "object",
        "properties": {
          "subObject1": { "type": "boolean" },
          "subObject2": { "type": "string"  }
        },
        "required": ["subObject1", "subObject2"],
        "additionalProperties": false
      }
    }
  },
  "else" : {
    "properties": { "myObject": { "type": "null" } }
  }
  
}

我在 jsonschema.dev 中有这个,但它给出了架构错误 "/properties/required" should be object,boolean。 我的基本模式正在运行,但我不确定如何根据另一个属性值添加此条件验证。

更新 1 我更新了架构,它现在被解析为有效。但是,当 ineligibleReason 有一个值并且 myObject 是一个对象而不是 null 时,有效负载会验证。

更新 2 我再次 updated the schema,将 if/then/else 移动到底部(不再是“内联”)。模式定义被解析为有效,但是无论无效情况如何,有效负载都会成功验证(ineligibleReason 有一个值并且 myObject 是一个对象而不是 null)。

如何让 if/then/else 正确验证我的 subObject 属性?

错误消息指出了问题所在。 /properties/required 正在声明一个名为“required”的 属性,然后它下面的值需要是一个模式(对象或布尔值)。因此,您需要将“必需”提升为与“属性”相邻,而不是在其下方。

Ryan Miller 在 json-schema Slack 上的回答。与我尝试的方法略有不同,但更简单且有效!

{
  "type": "object",
  "properties": {
    "topObj": {
      "type": "object",
      "properties": {
        "subItem1":         { "type": "string" },
        "subItem2":         { "type": "string" },
        "ineligibleReason": { "type": "string" },
        "myObject":         {
          "type": ["object", "null"],
          "$comment": "'properties', 'required', and 'additionalProperties' only make assertions when the instance is an object.",
          "properties": {
            "subObject1": { "type": "boolean" },
            "subObject2": { "type": "string"  }
          },
          "required": ["subObject1", "subObject2"],
          "additionalProperties": false
        }
      },
      "required": ["subItem1", "subItem2", "ineligibleReason", "myObject"],
      "additionalProperties": false,
      "if": {
        "$comment": "Is an ineligibleReason defined?",
        "properties": {
          "ineligibleReason": {"minLength": 1}
        }
      },
      "then": {
        "$comment": "Then 'myObject' must be null.",
        "properties": {
          "myObject": {"type": "null"}
        }
      }
    }
  },
  "required": ["topObj"],
  "additionalProperties": false
}