使用 json-schema 来要求或禁止基于另一个 属性 值的属性?

Use json-schema to require or disallow properties based on another property value?

我在 json-schema 中试图完成的事情:当 属性 enabledtrue 时,应该需要某些其他属性。当 false 时,这些属性应该被禁止。

这是我的 json-schema:

{
  "type": "object",
  "properties": {
    "enabled": { "type": "boolean" }
  },
  "required" : ["enabled"],
  "additionalProperties" : false,
  "if": {
    "properties": {
      "enabled": true
    }
  },
  "then": { 
    "properties": {
      "description" : { "type" : "string" },
      "count": { "type": "number" }
    },
    "required" : ["description", "count"]
  }
}

使用 ajv 版本 6.5 进行验证,结果是需要 count,等等,而不管 enabled 的值如何。例如,对于数据:

{ "enabled": false }

我的验证错误是:

[ { keyword: 'required',
    dataPath: '',
    schemaPath: '#/then/required',
    params: { missingProperty: 'description' },
    message: 'should have required property \'description\'' },
  { keyword: 'required',
    dataPath: '',
    schemaPath: '#/then/required',
    params: { missingProperty: 'count' },
    message: 'should have required property \'count\'' },
  { keyword: 'if',
    dataPath: '',
    schemaPath: '#/if',
    params: { failingKeyword: 'then' },
    message: 'should match "then" schema' } ]

如何使用 json-schema draft-7 完成此操作?

请注意,此问题与以下内容类似,但要求更严格:
.

试试这个模式:

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "if": {
    "properties": {
      "enabled": {
        "const": true
      }
    }
  },
  "then": {
    "properties": {
      "enabled": {
        "type": "boolean"
      },
      "description": {
        "type": "string"
      },
      "count": {
        "type": "number"
      },
      "additionalProperties": false
    },
    "required": [
      "description",
      "count"
    ]
  },
  "else": {
    "properties": {
      "enabled": {
        "type": "boolean"
      }
    },
    "additionalProperties": false
  }
}

如果需要 "additionalProperties": false,则必须枚举 thenelse 中的所有属性。如果您可以接受其他属性,架构可能会更简单:

{
  "type": "object",
  "properties": {
    "enabled": {
      "type": "boolean"
    }
  },
  "required": [
    "enabled"
  ],
  "if": {
    "properties": {
      "enabled": {
        "const": true
      }
    }
  },
  "then": {
    "properties": {
      "description": {
        "type": "string"
      },
      "count": {
        "type": "number"
      }
    },
    "required": [
      "description",
      "count"
    ]
  }
}

我检查了ajv cli

有效:{"enabled": false}

无效:{"enabled": true}

有效:{"enabled": true, "description":"hi", "count":1}

这是受 vearutop 出色回答的启发。我认为它可能会更短一些,并且达到了我所说的目的。

{
  "type": "object",
  "oneOf" : [
    {
      "properties": {
        "enabled": { "const": false }
      },
      "required": ["enabled"],
      "additionalProperties": false
    },
    {
      "properties": {
        "enabled": { "const": true },
        "description": { "type": "string" },
        "count": { "type": "number" }
      },
      "required": [ "enabled", "description", "count"],
      "additionalProperties": false
    }
  ]
}

正如评论中所指出的,这是 .

中阐明的 Enum 策略的特定变体

为此,您需要在 if 语句中使用 const 关键字,因此架构将如下所示:

{
  "type": "object",
  "properties": {
    "enabled": { "type": "boolean" }
  },
  "required" : ["enabled"],
  "additionalProperties" : false,
  "if": {
    "properties": {
      "enabled": {"const": true}
    }
  },
  "then": { 
    "properties": {
      "description" : { "type" : "string" },
      "count": { "type": "number" }
    },
    "required" : ["description", "count"]
  }
}