我正在尝试为json模式建模,该模式支持任意布尔表达式,如:
(prop1 > 'val1' || prop2 = 'val2') && !(prop3 in [1, 2, 3])
{
and: [
{
or: [
{ property: 'prop1', operator: 'gt', value: 'val1' },
{ property: 'prop2', operator: 'eq', value: 'val2' }
]
},
{
not: { property: 'prop3', operator: 'in', value: [1, 2, 3] }
}
]
}
这是迄今为止的模式:
{
"$ref": "#/definitions/BooleanExpression",
"definitions": {
"BooleanExpression": {
"oneOf": [
{ "$ref": "#/definitions/BooleanCondition" },
{ "$ref": "#/definitions/BooleanAnd" },
{ "$ref": "#/definitions/BooleanOr" },
{ "$ref": "#/definitions/BooleanNot" }
]
},
"BooleanOperator": {
"type": "string",
"enum": [
"eq",
"gt",
"gte",
"lt",
"lte",
"in"
]
},
"BooleanCondition": {
"type": "object",
"required": [
"property",
"operator",
"value"
],
"properties": {
"property": {
"type": "string",
"minLength": 1
},
"operator": {
"$ref": "#/definitions/BooleanOperator"
},
"value": {
"type": [
"string",
"number",
"boolean",
"null",
"array"
]
}
}
},
"BooleanAnd": {
"type": "object",
"required": [ "and" ],
"additionalProperties": false,
"properties": {
"and": {
"type": "array",
"minItems": 2,
"items": {
"$ref": "#/definitions/BooleanExpression"
}
}
}
},
"BooleanOr": {
"type": "object",
"required": [ "or" ],
"additionalProperties": false,
"properties": {
"or": {
"type": "array",
"minItems": 2,
"items": {
"$ref": "#/definitions/BooleanExpression"
}
}
}
},
"BooleanNot": {
"type": "object",
"required": [ "not" ],
"additionalProperties": false,
"properties": {
"not": {
"$ref": "#/definitions/BooleanExpression"
}
}
}
}
}
我想根据$.operator
字段的值来表达对BooleanCondition
中$.value
字段的允许类型的约束。例如,如果$.operator = in
,$.value
应该只是整数或字符串的数组:
{
property: 'prop1',
operator: 'in',
value: 'should not compile'
}
{
property: 'prop1',
operator: 'in',
value: ['this', 'is', 'ok']
}
或者,如果是$.operator = eq
,那么$.value
的类型可以是字符串、数字、布尔值或null(但不是数组(。
{
property: 'prop1',
operator: 'eq',
value: ['should', 'not', 'compile']
}
{
property: 'prop1',
operator: 'eq',
value: 'this is ok'
}
有可能在模式中表达这些类型的条件约束吗?
如其他问题所述,这是一个使用if-then-else语句的可能解决方案:
{
"$ref": "#/definitions/BooleanExpression",
"definitions": {
"BooleanExpression": {
"oneOf": [
{ "$ref": "#/definitions/BooleanCondition" },
{ "$ref": "#/definitions/BooleanAnd" },
{ "$ref": "#/definitions/BooleanOr" },
{ "$ref": "#/definitions/BooleanNot" }
]
},
"BooleanOperator": {
"type": "string",
"enum": [
"eq",
"gt",
"gte",
"lt",
"lte",
"in"
]
},
"BooleanCondition": {
"type": "object",
"required": [
"property",
"operator",
"value"
],
"properties": {
"property": {
"type": "string",
"minLength": 1
},
"operator": {
"$ref": "#/definitions/BooleanOperator"
},
"value": {
"type": [
"string",
"number",
"boolean",
"null",
"array"
]
}
},
"allOf": [
{
"if": {
"properties": {
"operator": {
"const": "in"
}
}
},
"then": {
"properties": {
"value": {
"type": "array",
"minItems": 1,
"items": {
"type": [
"string",
"number"
]
}
}
}
}
},
{
"if": {
"properties": {
"operator": {
"enum": [
"gt",
"gte",
"lt",
"lte"
]
}
}
},
"then": {
"properties": {
"value": {
"type": [
"string",
"number"
]
}
}
}
},
{
"if": {
"properties": {
"operator": {
"const": "eq"
}
}
},
"then": {
"properties": {
"value": {
"type": [
"string",
"number",
"boolean",
"null"
]
}
}
}
}
]
},
"BooleanAnd": {
"type": "object",
"required": [ "and" ],
"additionalProperties": false,
"properties": {
"and": {
"type": "array",
"minItems": 2,
"items": {
"$ref": "#/definitions/BooleanExpression"
}
}
}
},
"BooleanOr": {
"type": "object",
"required": [ "or" ],
"additionalProperties": false,
"properties": {
"or": {
"type": "array",
"minItems": 2,
"items": {
"$ref": "#/definitions/BooleanExpression"
}
}
}
},
"BooleanNot": {
"type": "object",
"required": [ "not" ],
"additionalProperties": false,
"properties": {
"not": {
"$ref": "#/definitions/BooleanExpression"
}
}
}
}
}