How do i define this jsonSchema rule - jsonschema

I have the jsonSchema like below
[{
"path": [
"General",
"label"
],
"type": "label",
"label": "Calculate Losses From Sub-Peril(s)",
"required": true
},
{
"path": [
"General",
"fire"
],
"type": "boolean",
"default": true,
"label": "Fire"
},
{
"path": [
"General",
"fireSmoke"
],
"type": "boolean",
"default": false,
"label": "Fire and Smoke"
}
],
I have the jsonSchema Rule as below. So if the user unchecks both fire and Fire and Smoke i want to fire a notification. How do i define JsonSchema Rule. Can some one fix this? I have the below rule but it gives me parser error. Atleast one checkbox has to be selected.
{
"path": [
"General",
"fire"
],
"effect": "fireNotification",
"notification": {
"type": "warning",
"message": "At least one Sub-Peril must be selected",
"notificationID": "fire",
"dismissible": "false"
},
"condition": {
"operator": "oneOf": {
"properties": {
"fire": {
"enum": [
true
]
},
"fireSmoke": {
"enum": [
true
]
}
}
}
}
}

Your JSON is invalid in two ways, both on the same line:
"operator": "oneOf": {
After "operator":, you need another opening brace ({) (and a matching closing brace later on.
The value of "oneOf": should be an array, so you need to add an opening bracket ([) there (and a matching closing bracket later on).
Further, you say "At least one checkbox has to be selected", but you are using a "oneOf" rule, not "anyOf". With "oneOf", if both properties are true, the validation will fail.

Related

Best Match for Validation error with oneof or anyof

I am trying to get proper validation error from oneof or anyof pattern. I have json schema with two or more oneof/anyof condition as mentioned below:
json_schema = {
"type": "object",
"properties": {
"comment": {
"description": "Server Pool Policy Qualification Comments",
"type": "string",
"default": ""
},
"name": {
"description": "Server Pool Policy Qualification Name",
"type": "string",
"default": "",
"pattern": "^[\\-\\.:_a-zA-Z0-9]{1,16}$"
},
"qualifications": {
"description": "Qualifications of Server Pool Policy Qualification",
"type": "array",
"items": {
"description": "Qualification of Server Pool Policy Qualification",
"type": "object",
"oneOf": [
{
"properties": {
"type": {
"description": "Qualification Type",
"type": "string",
"enum": [
"adapter"
]
},
"adapter_qualification":{
"description": "Adapter Qualifications - Adapter Type",
"type": "array",
"properties": {
"adapter_type": {
"description": "Adapter Qualifications - Adapter Type",
"type": "string",
"enum": [
"virtualized-scsi-if"
]
},
"adapter_pid": {
"description": "Adapter Qualifications - Adapter PID (RegEx)",
"type": "string",
"default": "",
"pattern": "[ !#$%\\(\\)\\*\\+,\\-\\./:;\\?#\\[\\\\\\]\\^_\\{\\|\\}~a-zA-Z0-9]{0,256}"
},
"adapter_maximum_capacity": {
"description": "Adapter Qualifications - Maximum Capacity",
"type": "string",
"default": "unspecified",
"pattern": "^unspecified$|^[0-9]$|^[0-9][0-9]$|^[0-9][0-9][0-9]$|^[0-9][0-9][0-9][0-9]$|^[0-5][0-9][0-9][0-9][0-9]$|^6[0-4][0-9][0-9][0-9]$|^65[0-4][0-9][0-9]$|^655[0-2][0-9]$|^6553[0-5]$"
}
},
"additionalProperties": False,
"required": [
"type",
"adapter_type"
]
}
}
},
{
"properties": {
"type": {
"description": "Qualification Type",
"type": "string",
"enum": [
"server_pid"
]
},
"server_pid": {
"description": "Server PID Qualifications - Server PID",
"type": "string",
"default": "",
"pattern": "^123$"
}
},
"additionalProperties": False,
"required": [
"type",
"server_pid"
]
}
]
}
}
},
"additionalProperties": False,
"required": [
"name"
]
}
I have data which has additional element first_rack_id but best matches 2nd element from oneof.
data = {
"descr": "description",
"name": "domainGroup",
"qualifications": [
{
"server_pid": "B200M5",
"type": "server_pid",
"first_rack_id": "10"
}
]
}
validator = Draft7Validator(json_schema)
best = best_match(validator.iter_errors(data))
My expectation is that the error message thrown by validation will find 2nd element from oneof and throw error saying additional property is not allowed. but i get match for 1st element as mentioned below:
'server_pid' is not one of ['adapter']
Failed validating 'enum' in schema[0]['properties']['type']:
{'description': 'Qualification Type',
'enum': ['adapter'],
'type': 'string'}
On instance['type']:
'server_pid'
how do i specify validator to best match with property "type" which will match with enum "server_pid" instead of enum "adapter"
You can specify which schema to validate against with the if/then keywords. It's a bit verbose and can be error prone, but it's the best way to express this sort of thing. Although popular, oneOf is almost never the right choice.
"allOf": [
{
"if": {
"type": "object",
"properties": {
"type": { "const": "adapter" }
},
"required": ["type"]
},
"then": { "$ref": "#/definitions/adapter" }
},
{
"if": {
"type": "object",
"properties": {
"type": { "const": "server_pid" }
},
"required": ["type"]
},
"then": { "$ref": "#/definitions/server-pid" }
}
],
Since best_match need a sort key to help match errors and the default key is to use most depth errors key, see:
best_match
relevance
So maybe you can use a less depth key to match the errors.(below function is just a draft test, you can use it as reference)
def match_less_path(error):
return len(error.path)
best = best_match(validator.iter_errors(data), match_less_path)
And I test the output like this:
Additional properties are not allowed ('first_rack_id' was unexpected)
Failed validating 'additionalProperties' in schema[1]:
{'additionalProperties': False,
'properties': {'server_pid': {'default': '',
'description': 'Server PID '
'Qualifications - Server '
'PID',
'pattern': '^123$',
'type': 'string'},
'type': {'description': 'Qualification Type',
'enum': ['server_pid'],
'type': 'string'}},
'required': ['type', 'server_pid']}
On instance:
{'first_rack_id': '10', 'server_pid': 'B200M5', 'type': 'server_pid'}

JSON-schema exclude properties (opposite to required properties)

in JSON-schema, one can require certain keys in an object, see this example, taken from the json schema docs:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "type": "string" },
"telephone": { "type": "string" }
},
"required": ["name", "email"]
}
I need the opposite: Is there a way to forbid or prevent a certain key from being in an object? Specifically, I want to prevent users from having an empty key inside an object:
{
"": "some string value"
}
You can exclude certain keys by name with:
{
"not": {
"anyOf": [
{ "required": [ "property1" ] },
{ "required": [ "property2" ] },
{ "required": [ "property3" ] },
...
]
}
https://json-schema.org/understanding-json-schema/reference/combining.html
Next to excluding keys with the not syntax (see answer by Ether), it is possible to achieve the goal with property-names.
In the following example, all keys have to map to a string URI. We furthermore exclude all keys that are not alphanumeric (via pattern), or don't have a specific length (via minLength). Other than that, we have no restrictions on keys.
"SomeKeyToBeValidated": {
"type": "object",
"properties": { },
"propertyNames": {
"type": "string",
"minLength": 1,
"pattern": "^[a-zA-Z0-9]*$"
},
"additionalProperties": {
"type": "string",
"format": "uri"
}
}

How do i write a json rule(validation) for the following schema

I have the following schema, so if i have more than one checkbox selected, i want to set the value of a hidden variable called peril. How do i write a rule for that The json is below
{
"path": [
"General",
"fire"
],
"type": "boolean",
"default": true,
"label": "Fire"
},
{
"path": [
"General",
"Smoke"
],
"type": "boolean",
"default": false,
"label": "Smoke"
},
{
"path": [
"General",
"Wind"
],
"type": "boolean",
"default": false,
"label": "Wind"
}
If Fire and Smoke are selected then the value of peril should be FR,SM.. How do i write a if else validation rule in jsonSchema?

Angular6 JSON schema form for Array of Items

I am trying out Angular6 JSON form for my application and stuck in the issue of having array schema
The basic layout looks like
{
"schema": {
"type": "array",
"properties": {
"type": { "type": "string" },
"number": { "type": "string" },
}
},
"layout": [
{
"type": "array",
"items": [ {
"type": "div",
"displayFlex": true,
"flex-direction": "row",
"items": [
{ "key": "type", "flex": "1 1 50px",
"notitle": true, "placeholder": "Type"
},
{ "key": "number", "flex": "4 4 200px",
"notitle": true, "placeholder": "Phone Number"
}
]
} ]
}
],
"data": [
{ "type": "cell", "number": "702-123-4567" },
{ "type": "work", "number": "702-987-6543" }
]
}
But I am not getting the expected outcome, that is Form is prefilled with the data
[
{ "type": "cell", "number": "702-123-4567" },
{ "type": "work", "number": "702-987-6543" }
]
Refer: https://hamidihamza.com/Angular6-json-schema-form/
Based on your code there are some parts you may need to revisit.
The schema type should be either an object or boolean based on the documentation http://json-schema.org/latest/json-schema-core.html
Within the schema section, it seems that you want the type and number to be your properties of a JSON instance. Having this you can only pass one instance of data to the framework to fill in your properties because the framework cannot decide on which value to use for your property of type string.
In case of looking for having an array of type and number, you can have a property like "phone number" with the type array. below is an example from angular6-json-schema flex layout example which I think you had as your reference.
"schema": {
...
"phone_numbers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": [ "cell", "home", "work" ] },
"number": { "type": "string" }
},
"required": [ "type", "number" ]
}
And pass your data having something as follows:
"data": {
...
"phone_numbers": [
{ "type": "cell", "number": "702-123-4567" },
{ "type": "work", "number": "702-987-6543" }
],
}

How can I achive that enable all checkboxes in jsonschema after I check radio button?

Okey. I have a jsonschema as below. I am trying to get all the items (colors - checkboxes) clicked by default when the radio button "YES" is marked. On the contrary, if the "NO" button is clicked, all the colors will be unchecked.
JsonSchema
{
"title": "Item Type Filtering Form",
"description": "Form for filtering Item Types according to selected Attribute Values.",
"type": "object",
"properties": {
"colorAll": {
"type": "boolean",
"title": "Seat Color All",
"enum": [
false,
true
],
"enumNames": [
"NO",
"YES"
],
"default": true
},
"colorList": {
"type": "array",
"title": "Seat Color",
"items": {
"type": "object",
"enum": [
{
"id": 1,
"label": "RED"
},
{
"id": 2,
"label": "BLUE"
},
{
"id": 3,
"label": "GREEN"
}
],
"enumNames": [
"RED",
"BLUE",
"GREEN"
]
},
"uniqueItems": true
}
}
}
UISchema
{
"colorAll": {
"ui:widget": "radio",
"ui:options": {
"inline": true
}
},
"colorList": {
"ui:widget": "checkboxes",
"ui:options": {
"inline": true
}
}
}
I am practising it on the page https://mozilla-services.github.io/react-jsonschema-form/# but none of my tries is working how I described above...
I thought, that I can make it with "default:" keyword and put all the values into it -> JsonSchema is valided, but it didn't work.
Can somebody help me with it?
Currently It does not seems to be possible
{
"title": "Schema dependencies",
"description": "These samples are best viewed without live validation.",
"type": "object",
"properties": {
"conditional": {
"title": "Conditional",
"$ref": "#/definitions/person"
}
},
"definitions": {
"person": {
"title": "Person",
"type": "object",
"properties": {
"colorAll": {
"type": "string",
"enum": [
"No",
"Yes"
],
"default": "No"
}
},
"required": [
"colorAll"
],
"dependencies": {
"colorAll": {
"oneOf": [
{
"properties": {
"colorAll": {
"enum": [
"Yes"
]
},
"colorList": {
"type": "array",
"title": "Seat Color",
"items": {
"type": "string",
"enum": [
"RED",
"BLUE",
"GREEN",
"Yes Only",
"ABC"
]
},
"default": [
"RED",
"BLUE",
"Yes Only"
],
"uniqueItems": true
}
}
},
{
"properties": {
"colorAll": {
"enum": [
"No"
]
},
"colorList": {
"type": "array",
"title": "Seat Color",
"items": {
"type": "string",
"enum": [
"RED",
"BLUE",
"GREEN"
]
},
"uniqueItems": true
}
}
}
]
}
}
}
}
}
if you run the above in playground, the list of colors changes, but it does not select the default ones. but if you have colorList has standalone component, it selects the default ones.
To change the default selected values, you need to use the "onChange" property of the form (https://react-jsonschema-form.readthedocs.io/en/latest/#form-data-changes) and handle that logic on your own. Thus, you can check if the radio button was toggled to true or false, and if so, set colorList to
[
{
"id": 1,
"label": "RED"
},
{
"id": 2,
"label": "BLUE"
},
{
"id": 3,
"label": "GREEN"
}
]
or [] respectively.
Note the following warning in the doc:
WARNING: If you have situations where your parent component can re-render, make sure you listen to the onChange event and update the data you pass to the formData attribute.
Here's an example codepen I set up that manages the two properties:
https://codepen.io/anon/pen/VOjJmY
Also note that because the actual value is an object, I think you have to reuse the same object (hence the direct use of schema.properties.colorList.items.enum).
I think there is a bug with React JSON Schema Form because the checkboxes' UI state doesn't get updated in the right lifecycle or something. The state is correctly updated, but I can't the un-toggle all/toggle all effect to happen on correct state, but rather the follow toggle... Like on going from "YES" -> "NO" -> "YES" they all switch off, and then going from "YES" -> "NO" they would switch back on...