json schema for one property dependent on another property's values - jsonschema

I have 2 properties I want to list out which are os_type and os_version.
os_type would be an enum with several values like windows, linux, etc.
based on the os_type, os_version values would be different enum values.
like for windows, os_version would be 7,8,10
for linux, os_version would be ubuntu, fedora etc
How can I do this with a json schema where os_version is dependent on the os_type and different enum values for os_version are displayed based on the os_type?
This is my current code snippet, not quite working.
{
"namespace": "MetadataOSVersion",
"display_name": "Company Metadata: OS Version",
"description": "Company Metadata: OS Version",
"visibility": "public",
"protected": true,
"objects": [
{
"name": "os_type",
"description": "os_type",
"properties": {
"os_type":
{
"title": "os_type",
"description": "os_type",
"type": "string",
"enum": ["Linux", "Windows"]
},
"os_version":
{
"title": "os_version",
"description": "os_version",
"type": "string",
"required": ["os_type"],
"oneOf": [
{{"os_type": {"enum": ["Windows"], "enum": ["7", "8", "10"]}}},
{{"os_type": {"enum": ["Linux"], "enum": ["Ubuntu", "Fedora"]}}}
]
}
}
}
]
}

Related

oneOf nested in array

I am currently testing JSON Forms on my schema (as is, without a UI definition), and I am running into the following problem: I can generate lists of options with oneOf (as shown in this_works below), but I am not able to do so within an array (this_does_not_work in the minimal example below). Instead, the array will simply offer simple text fields that validate against the options listed in oneOf.
Is there a way to achieve what I am trying to achieve here? Ideally, the UI of this_works (a list that users can select from) would appear for each line of the array:
{
"$id": "schema_test",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Minimal example",
"type": "object",
"properties": {
"this_works": {
"type": "string",
"oneOf": [
{
"const": "a",
"title": "Option A"
},
{
"const": "b",
"title": "Option B"
}
]
},
"this_does_not_work": {
"type": "array",
"items": {
"type": "string",
"oneOf": [
{
"const": "a",
"title": "Option A"
},
{
"const": "b",
"title": "Option B"
}
]
}
}
}
}```

reference multiple types in json schema array

I am trying to define an array property of an object in a json schema v7, but validation isn't working. How can I correctly reference multiple type definitions to be used in an array? Here an array for Directory can contain more directories or routes:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "RootDirectory",
"title": "Directory",
"description": "Build a directory for javascript app routing.",
"type": "object",
"definitions": {
"Route": {
"type": "object",
"description": "A simple endpoint declaration.",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "An endpoint without forward slashes.",
"examples": ["welcome"],
"minLength": 1
},
"variableSuffix": {
"description": "A string that is appended to the path variable name during build.",
"type": "string"
}
},
"required": ["path"]
},
"Directory": {
"type": "object",
"description": "Contains child directories or routes for recursive tree building.",
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "An endpoint without forward slashes.",
"examples": ["welcome"],
"minLength": 1
},
"variableSuffix": {
"description": "A string that is appended to the path variable name during build.",
"type": "string"
},
"childNodes": {
"minItems": 1,
"type": "array",
"description": "An array of routes, linkedRoutes, subDirectories, or linkedSubDirectories.",
"contains": {
"type": "object",
"oneOf": [
{"$ref": "#/definitions/Route"},
{"$ref": "#/definitions/Directory"}
]
}
}
},
"required": ["path", "childNodes"]
},
},
"properties": {
"directories":{
"type": "array",
"contains": {
"type": "object",
"allOf": [{"$ref": "#/definitions/Directory"}]
},
"minItems": 1
},
"rootPath": {
"type": "string",
"default": ""
}
},
"required": ["directories"]
}
for instance, this is valid and shouldn't be since it contains an object with invalid properties:
{
"rootPath": "api",
"directories": [
{
"path": "a",
"childNodes": [
{
"path": "a",
"variableSuffix": "s"
},
{
"invalidProperty" : "a"
}
]
}
]
}
Is the problem that the property /directories/0/childNodes/1/invalidProperty should not be permitted? The schema does not state that all the array items in childNodes must be valid -- it only specifies that childNodes must contain a valid item, and item #0 does validate, therefore the overall schema validates.
To assert that all the items in childNodes must be valid, change contains at /definitions/Directory/properties/childNodes/contains to items -- the items keyword specifies a schema that must be validated against all array items, whereas contains only asserts that at least one array item must validate.

Json schema conditional validation configuration - Unsupported keyword(s): ["const"]]

I want to set up the conditional validation in my schema. I saw an example here on SO.
I have a similar setup, where I would like to validate if the field public is set to string "public". If it is set to "public" then I want to make fields description, attachmentUrl and tags required. If the field is not set to "public" then this fields are not required.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Update todo",
"type": "object",
"properties": {
"public": {
"type": "string"
},
"description": {
"type": "string",
"minLength": 3
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true,
"minItems": 1
},
"attachmentUrl": {
"type": "string"
}
},
"anyOf": [
{
"not": {
"properties": {
"public": { "const": "public" }
},
"required": ["public"]
}
},
{ "required": ["description", "tags", "attachmentUrl"] }
],
"additionalProperties": false
}
But, when I try to deploy it like that, I get the following error:
Invalid model specified: Validation Result: warnings : [], errors :
[Invalid model schema specified. Unsupported keyword(s): ["const"]]
The "const" keyword wasn't added until draft 06. You should upgrade to an implementation that supports at least that version.
https://json-schema.org/draft-06/json-schema-release-notes.html#additions-and-backwards-compatible-changes
Otherwise, you can use "enum" with a single value: "enum": ["public"]

Load Avro file to GCS with nested record using customized column name

I was trying to load an Avro file with nested record. One of the record was having a union of schema. When loaded to BigQuery, it created a very long name like com_mycompany_data_nestedClassname_value on each union element. That name is long. Wondering if there is a way to specify name without having the full package name prefixed.
For example. The following Avro schema
{
"type": "record",
"name": "EventRecording",
"namespace": "com.something.event",
"fields": [
{
"name": "eventName",
"type": "string"
},
{
"name": "eventTime",
"type": "long"
},
{
"name": "userId",
"type": "string"
},
{
"name": "eventDetail",
"type": [
{
"type": "record",
"name": "Network",
"namespace": "com.something.event",
"fields": [
{
"name": "hostName",
"type": "string"
},
{
"name": "ipAddress",
"type": "string"
}
]
},
{
"type": "record",
"name": "DiskIO",
"namespace": "com.something.event",
"fields": [
{
"name": "path",
"type": "string"
},
{
"name": "bytesRead",
"type": "long"
}
]
}
]
}
]
}
Came up with
Is that possible to make the long field name like eventDetail.com_something_event_Network_value to be something like eventDetail.Network
Avro loading is not as flexible as it should be in BigQuery (basic example is that it does not support load a subset of the fields (reader schema). Also, renaming of the columns is not supported today in BigQuery refer here. Only options are recreate your table with the proper names (create a new table from your existing table) or recreate the table from your previous table

JSON Schema to represent a name and value with value constrained by name

I have the following JSON snippets which are all valid
"units": { "name": "EU", "value": "Grams" }
"units": { "name": "EU", "value": "Kilograms" }
"units": { "name": "US", "value": "Ounces" }
"units": { "name": "US", "value": "Pounds" }
The name values can be EU and US and the valid value value should depend on the name value.
It's easy to use JSON Schema enums for both these properties, but can I enforce the additional constraint using JSON Schema?
I would consider changing the overall schema so that there is a parent child relationship between a name object and value object, but ideally this would be avoided.
I managed to crack it using https://www.jsonschemavalidator.net/ to work though an example. The following schema provides the solution:
"units": {
"type":"object",
"oneOf": [ {
"properties": {
"name": { "enum": [ "EU" ] },
"value": { "enum" : ["Grams", "Kilograms"]}}}, {
"properties": {
"name": { "enum": [ "US" ] },
"value": { "enum": ["Ounces", "Pounds"]}}}]
}