JSON Schemas feature enums, which impose a constraint on the values of a string type:
{
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
},
{
"type": "string",
"enum": ["NW", "NE", "SW", "SE"]
}
]
}
此架构验证[1600, "Pennsylvania", "Avenue", "NW"]
等值。
是否有一种优雅的方法可以使enum
不区分大小写,以便Avenue
和avenue
都被接受为数组中的第三个值?
我可以在值列表中使用anyOf
,并针对不区分大小写的正则表达式验证每个值 - 但这很麻烦,容易出错并且不够优雅。
答案 0 :(得分:5)
我担心你找不到任何优雅的解决方案。有case-insensitive enums and several issues were commented的提案。
因此,如果您无法避免这种要求,那么正则表达式解决方案是唯一可行的解决方案。另一种蛮力方法是拥有n个完整的枚举值列表,一个带有起始大写字母,另一个带有大写字母等,然后按照你的说法使用anyOf。您可以轻松地自动创建此json-schema。显然它不会非常易读。
无论如何,我会尝试在验证前通过预处理步骤来解决这个问题。如果存在,您可以将所需属性转换为小写,然后进行验证。我发现有点被迫使用json-schema规范来允许'脏'数据。
答案 1 :(得分:0)
我最终创建了2个助手,将字符串转换为不区分大小写的模式,并将其转换回小写版本:
const toCaseInsensitive = (v = "") =>
v
.split("")
.map(l => {
const lower = l.toLowerCase()
const upper = l.toUpperCase()
return lower === upper ? lower : `[${lower}|${upper}]`
})
.join("")
const fromCaseInsensitive = (v = "") => v.replace(/\[(.)\|(.)\]/g, "$1")
用法:
toCaseInsensitive("TeSt") -> "[t|T][e|E][s|S][t|T]"
fromCaseInsensitive("[t|T][e|E][s|S][t|T]") -> "test"
答案 2 :(得分:0)
transform
中提供的 Ajv-Keywords 方法可用于不区分大小写的枚举。
AjvKeywords(ajv, 'transform');
{
"type": "array",
"items": [
{
"type": "string",
"enum": ["NW", "NE", "SW", "SE"],
"transform": ["toLowerCase"],
}
]
}
答案 3 :(得分:0)
我们可以使用模式实现下面枚举的大小写不敏感。但是 json 架构不支持 /i
用于正则表达式不敏感。所以我们可以用我们自己的正则表达式模式来实现,而无需使用 /i
。
枚举:
month: { type: 'string', enum: ['may', 'June', 'July'] },
正则表达式:
month: { type: 'string', pattern: '^([Mm][Aa][Yy]|[Jj][Uu][Nn][Ee]|
[Jj][Uu][Ll[Yy])$',},
上面的正则表达式是为 May, June, July 的值之一,不区分大小写