JSON模式枚举可以不区分大小写吗?

时间:2014-10-28 09:24:54

标签: enums case-insensitive jsonschema

JSON Schema枚举

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不区分大小写,以便Avenueavenue都被接受为数组中的第三个值?

其他可能的解决方案

我可以在值列表中使用anyOf,并针对不区分大小写的正则表达式验证每个值 - 但这很麻烦,容易出错并且不够优雅。

4 个答案:

答案 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 的值之一,不区分大小写