how to override minItems in Jsonschema when referencing - json

I am trying to reference a property from a json schema to another but I need to override the minItems.
in a file called Rand.json
"Rn": {
"type": "array",
"minItems": 2,
"items": {
"type": "string"
},
}
I want to use the Rn in Rand.json in another json schema but I have to override the minitems to 1 how can I do this.
I tried over-riding them like this:
"Rn": {
"minItems": 1,
"$ref": "Rand.json#/definitions/Rn"
}
But When I tried to run it over with the examples I get error.
Failed validating 'minItems' in schema['properties']['Rn']:

Related

Json Schema - validate pattern for string inside an array is ignored

I have a schema defined this way:
"permissions": {
"type": "array",
"properties": {
"items":
{
"$ref": "#/definitions/permissionsType"
}
}
},
and permissionsType:
"permissionsType": {
"type": "string",
"pattern": "^[a-zA-Z0-9]+(:[a-zA-Z0-9][a-zA-Z0-9-]+)+$"
},
...
I am not sure why the pattern regex is ignored.
Remove the properties keyword and it will work as expected.
I'm not sure what you're trying to do with the properties keyword here. properties only applies when the instance being validated is an object. Because the instance is an array, properties is ignored. If the instance were an object, the properties keyword would apply, but it would be expecting an object with a property name "items" that matches #/definitions/permissionsType. I don't think that's what you meant. I think you wanted an array whose items all match #/definitions/permissionsType.
"permissions": {
"type": "array",
"items": { "$ref": "#/definitions/permissionsType" }
}

Validate each JSON node with different JSON schema

Im trying to make a system monitor, which is highly customisable by user. This customization is achieved by using JSON file for modeling look of system monitor. The JSON could look like this.
{
"_": "WINDOW",
"name": "myWindow",
"children": [
{
"_": "CPU",
"name": "cpuMonitor",
"freq_Unit": "MHZ"
},
{
"_": "NETWORK",
"name": "network",
"unit": "Kb/s"
},
{
"_": "DISK",
"name": "disk"
}
],
"background": "red"
}
As you can see, each object coresponds to this schema.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"name":"Component",
"type": "object",
"properties":{
"_": {
"type": "string"
},
"name":{
"type":"string"
},
"childern":{
"type":"array"
}
},
"required": ["_","name"]
}
But each component has also its own schema definition. I'd like to parse whole JSON and validate each node for different schema (first if its component and then to its corresponding schema).
I had look at rapidJson and other libraries, but I didnt find solution for validating nodes for different schema. Do you know any library which could do that? Or is it even possible to validate JSON in this way?
All feedback on how to solve this will be appreciated.
Edit: Corrected schema :(
There's a simple approach involved with that, use the oneOf pattern declaration to specify the layout of the array elements. Inside these nested declarations, you specify the fixed identifier (probably the content of your _ field) as a constant, so that there is only one nested schema matching each of your panel types.
Notes:
I had to specify the constant type identifier using the enum specifier because the regular constant specifier didn't work with the library I was using. This may also have been an oversight in the revision of the specification that it was based on.
A different approach is to split the the validation steps. You simply verify that the elements of the array are objects and that they have a string field _ containing one of the supported types. When iterating over the array, you then validate each field individually according to its _ field.
In addition to Ulrich's answer, here's an example of what I'd do:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Component",
"type": "object",
"definitions": {
"base": {
"properties": {
"name": { "type": "string" },
"children": {
"type": "array",
"items": { "$ref": "#" }
}
},
"required": [ "_", "name" ]
},
"cpu": {
"properties": {
"_": { "const": "CPU" },
"freq_Unit": "MHZ"
}
},
"network": {
"properties": {
"_": { "const": "NETWORK" },
"unit": "Kb/s"
}
},
"disk": {
"properties": {
"_": { "const": "DISK" }
}
},
"window": {
"properties": {
"_": { "const": "WINDOW" },
"background": { "enum": [ "red", "orange", "yellow", ... ] }
}
}
},
"allOf": [
{ "$ref": "#/definitions/base" },
{
"oneOf": [
{ "$ref": "#/definitions/cpu" },
{ "$ref": "#/definitions/network" },
{ "$ref": "#/definitions/disk" },
{ "$ref": "#/definitions/window" }
]
}
]
}
First, we require that any instance MUST adhere to base which declares _ and name as required properties. Additionally, we declare a children array property that requires all items also match this schema (giving us a recursive behavior). This doesn't really do much except that it allows us to declare these things in one place instead of having to declare them in the other three definitions.
(Note that we don't declare _ in the properties list. This means that any value will pass for this portion of the schema. We clean it up in the next part. If you want to ensure that future components are declared with strings, then you can add a "type": "string" requirement to that property, but I don't feel it's necessary unless others are authoring those components.)
Second, we declare each of our specific types as separate definitions, using the const keyword to isolate the one we want. This construct is analogous to a switch (or case) statement. If the instance doesn't match one of these explicit options, it fails. If it's missing one of the required base properties, it fails.
This will get you where you want to be.
To take it further, there are two more things you can do:
Add required to the other definitions to say that the specific properties are also required (e.g. freq_Unit for the cpu definition).
Declare each of the definitions in separate files. This would allow you to add a new definition by simply adding a new file and referencing it in the main schema. In my opinion, it's a bit cleaner. Some people prefer to have it all in one file, though.

JSONSchema: add extra constraints to property derived from ref

I have a large library of JSONSchemas and I'd like to structure it as follows:
my_object.json # a canonical definition of my_object
create_my_object_response.json # a response to a request to create a particular my_object
In this setup, my_object.json would define a general format of my_object, while create_my_object_response.json would expect some particular values for the fields of my_object. I'd like to structure the create_my_object_response.json schema like this:
{
"type": "object",
"definitions": {},
"$schema": "http://json-schema.org/draft-06/schema#",
"allOf": [
{ "$ref": "my_object.json#" },
{
"type": "object",
"properties": {
"id": { "const": 2 },
"name": { "const": "A Specific Name" }
}
}
]
}
my_object.json contains both the id and name properties but doesn't specify the const values. I tried this setup but it didn't seem to work. How can I represent this? Is it even possible?
I managed to figure this out, so posting the answer here for posterity.
The construction I had was actually right, but instead of "const": 2 I switched to "enum": [2]. I think this had to do with the version of the schema I was using.

Multiple schema JSON validation in Golang

I need to validate several JSON files against a schema in Golang.
I have been able to achieve it by using gojsonschema, that is really a straight forward library.
However, the problem I'm facing right now is that I have been given with schemas that have dependencies to another schemas and haven't found the way to load all the schemas that I need. Therefore, my validations always fail.
This is my main schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/List",
"definitions": {
"List": {
"type": "array",
"items": {
"$ref": "#/definitions/Item"
}
},
"Item": {
"description": "An item ....",
"type": "object",
"additionalProperties": false,
"properties": {
"property01": {
"description": "The property01 code.",
"$ref": "./CommonTypes.json#/definitions/Type01Definition"
}
},
"required": [
"property01"
]
}
}
}
And, I have another one with common types:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"Type01Definition": {
"description": "The definition for the type 01",
"type": "string",
"pattern": "^[A-Z0-9]{3}$"
}
}
}
Is there a way to load several schemas using that library? Or is there any other Golang library that allows to achieve that?
The way to refer to a file using $ref is to specify the absolute path of the file using a URL scheme. If you change the $ref to look like "$ref" : "file:///home/user/directory/CommonTypes.json#/definitions/Type01Definition, your example will work as expected.
If you need a bit more flexibility you can either try gojsonschema's NewReferenceLoaderFilesystem or switch to a different Golang library https://github.com/santhosh-tekuri/jsonschema. That library allows you to add custom resources so you can load several schemas at once.

JSON Schema Dependencies remove key if another key present without using oneOf as it is not supported by alpacajs

I am using a alpacajs library to construct my json schema into a form that doesnt support oneOf keyword.
I have a simple requirement where if one field is present then the other one should be hidden.
Is there a way to implement using json schema itself without using oneOf keyword.
Right now i am using dependencies keyword to handle my conditions.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Company Setup",
"description": "Company Wizard Setup",
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Company Name"
},
"alternate_names": {
"type": "array",
"title": "Alternate Name",
"items": {
"type": "string"
},
"maxItems": 5
}
},
"dependencies": {
"name": "alternate_names"
}
}
{
"options": {
"fields": {
"name": {
"dependencies": {
"alternate_names": "Value for empty Array?"
}
},
"alternate_names": {
...
}
}
}
}
This is just a stripped down version of my schema for the sake of clarity and i would appreciate if anyone can help me tell if dependencies can be used to remove a field too. I could potentially just use javascript to get this but i wanted to handle this just using schema as i am going to use same for validation too, infact schema has more use as a validator than form itself.
Since none of the field is boolean, i can't just put true and false in value.
Thanks in advance.