如何简化多个 JSON-Schema switch-like 语句
How to simplify multiple JSON-Schema switch-like statements
JSON 架构文档中有一个类似开关条件的示例。
https://json-schema.org/understanding-json-schema/reference/conditionals.html
我在示例中又添加了两个国家/地区,这两个国家/地区的邮政编码模式应与荷兰相同。我可以让这个例子与两个额外的 if/then
结构一起工作,但是当要添加更多项目时它会变得混乱。
是否有DRYer版本,例如喜欢下面的假设吗?
"properties": { "country": { "const": ["Netherlands", "Upperlands", "Lowerlands" } }
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": ["United States of America", "Canada", "Netherlands",
"Upperlands","Lowerlands"]
}
},
"allOf": [
{
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
}
},
{
"if": {
"properties": { "country": { "const": "Canada" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
{
"if": {
"properties": { "country": { "const": "Netherlands" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
}
}
]
}
您可以改用枚举模式。它不那么冗长也更容易阅读,但是你得到的错误信息很糟糕,所以我建议你坚持使用 if/then 模式。这是使用枚举模式的样子。
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": ["United States of America", "Canada", "Netherlands",
"Upperlands","Lowerlands"]
}
},
"anyOf": [
{
"properties": {
"country": { "const": "United States of America" },
"postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" }
}
},
{
"properties": {
"country": { "const": "Canada" },
"postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" }
}
},
{
"properties": {
"country": { "const": "Netherlands" },
"postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" }
}
}
]
}
虽然没有解决冗长的好方法,但您可以做一些改进 readability/maintainability。您可以使用定义来隐藏冗长的部分。
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": ["United States of America", "Canada", "Netherlands",
"Upperlands","Lowerlands"]
}
},
"allOf": [
{ "$ref": "#/definitions/validate-us-postal-code" },
{ "$ref": "#/definitions/validate-ca-postal-code" },
{ "$ref": "#/definitions/validate-nl-postal-code" }
]
"definitions": {
"validate-us-postal-code": {
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
}
},
"validate-ca-postal-code": {
"if": {
"properties": { "country": { "const": "Canada" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
"validate-nl-postal-code": {
"if": {
"properties": { "country": { "const": "Netherlands" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
}
}
}
}
这使得某人仅通过阅读前几行就能够理解该架构所做的一切。 verbose/complicated 东西被推到底部,如果你不需要,你不必处理它。
JSON 架构文档中有一个类似开关条件的示例。
https://json-schema.org/understanding-json-schema/reference/conditionals.html
我在示例中又添加了两个国家/地区,这两个国家/地区的邮政编码模式应与荷兰相同。我可以让这个例子与两个额外的 if/then
结构一起工作,但是当要添加更多项目时它会变得混乱。
是否有DRYer版本,例如喜欢下面的假设吗?
"properties": { "country": { "const": ["Netherlands", "Upperlands", "Lowerlands" } }
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": ["United States of America", "Canada", "Netherlands",
"Upperlands","Lowerlands"]
}
},
"allOf": [
{
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
}
},
{
"if": {
"properties": { "country": { "const": "Canada" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
{
"if": {
"properties": { "country": { "const": "Netherlands" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
}
}
]
}
您可以改用枚举模式。它不那么冗长也更容易阅读,但是你得到的错误信息很糟糕,所以我建议你坚持使用 if/then 模式。这是使用枚举模式的样子。
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": ["United States of America", "Canada", "Netherlands",
"Upperlands","Lowerlands"]
}
},
"anyOf": [
{
"properties": {
"country": { "const": "United States of America" },
"postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" }
}
},
{
"properties": {
"country": { "const": "Canada" },
"postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" }
}
},
{
"properties": {
"country": { "const": "Netherlands" },
"postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" }
}
}
]
}
虽然没有解决冗长的好方法,但您可以做一些改进 readability/maintainability。您可以使用定义来隐藏冗长的部分。
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"enum": ["United States of America", "Canada", "Netherlands",
"Upperlands","Lowerlands"]
}
},
"allOf": [
{ "$ref": "#/definitions/validate-us-postal-code" },
{ "$ref": "#/definitions/validate-ca-postal-code" },
{ "$ref": "#/definitions/validate-nl-postal-code" }
]
"definitions": {
"validate-us-postal-code": {
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
}
},
"validate-ca-postal-code": {
"if": {
"properties": { "country": { "const": "Canada" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
"validate-nl-postal-code": {
"if": {
"properties": { "country": { "const": "Netherlands" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
}
}
}
}
这使得某人仅通过阅读前几行就能够理解该架构所做的一切。 verbose/complicated 东西被推到底部,如果你不需要,你不必处理它。