我将属性列表定义为 json 模式:
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"definitions": {
"attribute": {
"type": "object",
"properties": {
"symbolic-name": { "type":"string"},
"value": { "type":"string"}
},
"required": ["symbolic-name", "value"]
},
"displayname": {
"type": "object",
"properties": {
"symbolic-name": {"enum":["displayName"]},
"value": { "type":"string"}
},
"required": ["symbolic-name", "value"]
}
},
"properties": {
"attributes":{
"type": "array",
// This is the crucial point:
"items": {"oneOf": [
{"$ref": "#/definitions/attribute"},
{"$ref": "#/definitions/displayname"}
]},
"uniqueItems": true
}
}
}
我想要求列表只有一个属性 symbolic-name="displayName"
一个有效的数据对象是:
{
"attributes":[
{"symbolic-name": "displayName", "value": "Display Name"},
{"symbolic-name": "somethingElse", "value": "value1"}
{"symbolic-name": "somethingElse", "value": "value2"}
]
}
现在,这无法验证,因为 displayName 属性不仅匹配“oneOf”,而且两个限制都匹配。我无法将其更改为“allOf”,因为那样除 displayName 之外的所有其他属性将不再匹配。
为了让你"oneOf"
的工作,你需要你的“属性”和“显示名称”模式是相互排斥的——正如所写的那样,任何有效的“显示名称”也是一个有效的“属性”。我们可以通过排除“displayName”作为“attribute”的有效符号名称来做到这一点:
"symbolic-name": {
"type": "string",
"not": {"enum": ["displayName"]}
}
现在具有“displayName”符号名称的元素可以匹配“displayname”定义,但永远不会匹配“attribute”定义。
您问题的另一部分是关于您的阵列中只有一个“显示名称”。这更棘手。它还取决于您使用的 JSON Schema 草稿。4 和 6 已实施,7 已于周一发布 - 只是声明"$schema": "http://json-schema.org/schema#"
意味着您正在使用最新的,即 7。我建议使用特定的草案$schema
代替未编号的草案,因为它可能会更改,恕不另行通知。
如果您同意将“显示名称”作为数组的第一个元素,那么这将适用于任何草稿(您甚至不需要"oneOf"
):
"items": [{"$ref": "#/definitions/displayname"}],
"additionalItems": {"$ref": "#/definitions/attribute"}
注意"items"
这里是一个数组。这意味着第一项必须是“显示名称”,除第一项之外的所有其他项都必须是“属性”。
如果你想在任何位置允许“显示名”,那就更难了。从draft-06 开始,有"contains"
,它需要至少一项来匹配给定的模式。但是没有简单的方法可以说“最多一个项目”。然而,"minContains"
和"maxContains"
已经提出了草案,08:https://github.com/json-schema-org/json-schema-spec/issues/441
现在,希望您同意要求第一个位置是“显示名称”,因为这将适用于所有草稿。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句