【问题标题】:JSON Schema if/then/else for property that can be an object or null based on another properties valueJSON Schema if/then/else 用于可以是对象或基于另一个属性值的 null 的属性
【发布时间】:2021-11-11 17:49:42
【问题描述】:

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

例如,这个示例有效载荷

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

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

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

这是我目前所拥有的。 jsonschema.dev 认为它是一个有效的模式,但是当我在有效负载中向 inligibleReason 添加一个值(将 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 我更新了架构,现在它被解析为有效。但是,当 ineliibleReason 有一个值并且 myObject 是一个对象而不是 null 时,有效负载会进行验证。

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

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

【问题讨论】:

    标签: postman jsonschema ajv


    【解决方案1】:

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

    【讨论】:

    • 我调整了架构定义,将最后一个 required/additionalProperties 下移了一级。我还从 topObj 中删除了 required/additionalProperties,因为它会导致架构错误。我会在 if/then/else 工作后解决这个问题。即使 schema def 解析成功,它也没有根据我添加到问题定义中的真值表进行验证。
    • @Jim 您还需要将if/then/else 关键字移出properties
    • @JasonDesrosiers 我把它移出了属性。我在想条件逻辑上属于内联。架构定义似乎有效,但无效的有效负载验证成功。这是example of an invalid payload passing validation
    • @Jim 您的下一个问题是您不能在属性名称中使用点表示法。您可以使用点,但它们只是属性名称的一部分。你需要用像properties { topObj: { properties: { ineligibleReason: { const: "" } } } }这样的长格式来表达它。
    【解决方案2】:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2019-10-12
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-07
      • 2022-01-23
      相关资源
      最近更新 更多