I would like to create schema which allows me to add multiple addresses when the following is true:
1)Correspondence address must be there
2)Residence address must be there
3)Other types of addresses could be there
4) They can appear in any order
Is this possible to solve with JSON schema? I heard about "contains" in draft 6. But since we are using Altova XML SPY (2018), which is only supporting draft 4, for schema creation, I would like to know how to solve this in draft 4. Are you aware of any good editor for draft 6?
I read JSON schema to enforce array contents but cannot find the answer there. I also read https://gist.github.com/anonymous/7359001 which explains how to have "contains" in draft 4, but was unable to apply it to my case.
So if you can guide me, how to use it for the following schema(which fullfills my requirements except number 4), I would be very thankfull.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Comment describing your JSON Schema",
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Corespondence"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Residence"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
}
],
"additionalItems": {
"$ref": "#/definitions/Address"
}
}
},
"definitions": {
"Address": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Corespondence",
"Residence",
"Other"
]
},
"otherData": {}
},
"required": [
"type",
"otherData"
]
}
}
}
draft-06 has "contains" keyword allowing to test the presence of items matching the schema in the array.
Alternatively, instead of heterogenous array you could use a map with difference address types defined in different properties, so your data could be:
{
addresses: {
correspondence: {/*...*/},
residence: {/*...*/}
// etc...
}
}
The reason contains was added to draft-06 is that it is not possible to accomplish the same thing with draft-04 keywords.
There are several implementations supporting draft-06 on the software page: http://json-schema.org/implementations.html
Related
This seems to be the most authoritative documentation that I've found so far: https://docs.metaplex.com/nft-standard
{
"name": "Solflare X NFT",
"symbol": "",
"description": "Celebratory Solflare NFT for the Solflare X launch",
"seller_fee_basis_points": 0,
"image": "https://www.arweave.net/abcd5678?ext=png",
"animation_url": "https://www.arweave.net/efgh1234?ext=mp4",
"external_url": "https://solflare.com",
"attributes": [
{ "trait_type": "web", "value": "yes" },
{ "trait_type": "mobile", "value": "yes" },
{ "trait_type": "extension", "value": "yes" }
],
"collection": { "name": "Solflare X NFT", "family": "Solflare" },
"properties": {
"files": [
{
"uri": "https://www.arweave.net/abcd5678?ext=png",
"type": "image/png"
},
{
"uri": "https://watch.videodelivery.net/9876jkl",
"type": "unknown",
"cdn": true
},
{ "uri": "https://www.arweave.net/efgh1234?ext=mp4", "type": "video/mp4" }
],
"category": "video",
"creators": [
{ "address": "SOLFLR15asd9d21325bsadythp547912501b", "share": 100 }
]
}
}
These same docs state clearly that many fields are optional and should be omitted when not used. But which fields are required and which ones are optional?
Depends what you want to use it for. The simplest requirements I have used were:
{
"name": "Solflare X NFT",
"seller_fee_basis_points": 0,
"image": "https://www.arweave.net/abcd5678?ext=png",
"properties": {
"files": [
{
"uri": "https://www.arweave.net/abcd5678?ext=png",
"type": "image/png"
}
],
"category": "image",
"creators": [
{ "address": "SOLFLR15asd9d21325bsadythp547912501b", "share": 100 }
]
}
}
There is no reason to not include the rest as the cost of hosting this off-chain is minimal. I think most things would be optional but the important ones for an NFT would be the image attribute, as otherwise the NFT wont be able to be displated anywhere, and probably then the propertiess field because some wallets, DApps and marketplaces might use these fields to check file type. Creators should also be added if you want to receive royalties and without this field could result in your collection failing to be listed on marketplaces.
A short answer though, the minimum is not defined anywhere as removing certain things could break certain third party DApps. Depending how/where you want to use your NFT I would find out the requirements if you are desperately trying to minimise the metadata. Otherwise try to keep most of it.
I created the following draft4 schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$id": "catalog.structs.schema.json",
"definitions": {
"geography": {
"type": "object",
"description": "Geographical location which may or may not be part of a hierarchy.",
"properties": {
"geography_type": {
"type": "string",
"enum": ["union", "country", "state"]
},
"name": {
"type": "string",
"enum": ["Turkey", "Netherlands"]
},
"parent": {
"type": "object",
"$ref": "#/definitions/geography"
}
},
"required": ["name"]
},
"geography_group": {
"type": "array",
"description": "A grouping of discrete geographies that are not necessarily in a common hierarchy.",
"items": {
"type" : "object",
"$ref": "#/definitions/geography"
}
}
},
"oneOf": [{
"properties": {
"geography": { "type": "object", "$ref": "#/definitions/geography"},
"geography_group" : { "type": "object", "$ref": "#/definitions/geography_group"}
},
"additionalProperties": false
}]
}
The following validates correctly against the schema
{"geography":{"name":"Turkey", "geography_type":"country"}}
However, the following fails stating that the required property name is missing.
{"geography_group":[{"geography":{"name":"Turkey", "geography_type":"country"}}]}
If I remove "required": ["name"] it works, but I don't want to remove this.
What am I doing wrong?
There are a few misconceptions here, but you broadly have the right idea.
I'm not sure what you believe the oneOf is doing here. In this case, it simply isn't required, and you can put properties and additionalProperties straight in the root schema.
In terms of your problem, while you've defined geography as a property at the root level, you haven't done so for an item object in the geography_group value array.
You want to change your geograph_group definition to the following...
"geography_group": {
"type": "array",
"description": "A grouping of discrete geographies that are not necessarily in a common hierarchy.",
"items": {
"properties": {
"geograph": {
"$ref": "#/definitions/geography"
}
}
}
}
As an aside, in draft-04 of JSON Schema, any keywords alongside $ref are ignored.
The key you use in the definitions object has no bearing on the validation of your data.
I would like to constrain a (tuple) array in JSON-schema, and get decent error messages but so far I was unsuccessful.
The array consists of 2 items, the first is a string, and the second is an object. The properties that are allowed/required in the object depends on the string.
2 valid examples would be:
{
"color": [ "white", { "a white property": 42 }]
}
and
{
"color": [ "black", { "this is a black property": "tAttUQoLtUaE" }]
}
for reference, the type in typescript would be defined as:
type MyObject = {
color:
| ["white", {
"a white property": number
}]
| ["black", {
"this is a black property": string
}]
}
I have tried 'oneOf' (see below), and it works, but if the file is not valid, the error message is uncomprehensible.
You can try this instance at jsonschemavalidator.org:
{
"color": [ "black", {
"XXX": "foo"
}]
}
My attempt:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"required": [
"color"
],
"properties": {
"color": {
"oneOf": [
{
"type": "array",
"items": [
{
"enum": [ "white"]
},
{
"type": "object",
"required": [ "a white property" ],
"additionalProperties": false,
"properties": {
"a white property": {
"type": "number"
}
}
}
]
},
{
"type": "array",
"items": [
{
"enum": ["black"]
},
{
"type": "object",
"required": [ "this is a black property" ],
"additionalProperties": false,
"properties": {
"this is a black property": {
"type": "string"
}
}
}
]
}
]
}
},
"additionalProperties": false
}
Is there a better way to express this rule?
See, jsonSchema attribute conditionally required, for a description of four strategies for conditional constraints. Here they are in order of which strategy produces the best error messages.
dependencies: This is a very specific constraint, so it tends to have great error messages. Unfortunately, this doesn't work in your situation.
if/then: This is going produce the best messages in your case.
Implication: This produces pretty good error messages, but not quite as good as if/then. if/then was added in draft-07. If you can't use draft-07 or higher, this is your best bet.
Enum: This is the one you are using and it produces awful errors as you have seen. This is the worst option for error messaging.
Hi I have an index in Elasticsearch 2 which contains this definition of property contacts:
...
,
"contacts": {
"properties": {
"domains": {
"type": "string",
"index": "not_analyzed"
},
"emails": {
"type": "string",
"index": "not_analyzed"
},
"phones": {
"type": "string",
"index": "not_analyzed"
}
}
},
...
and as I see data in this index for contacts property contains arrays istead of string as mapping says. How is it possible?
"contacts": {
"domains": [
"http://www.xxxxx.sk",
"http://www.sssss.sk",
"http://ddddd.sk",
"http://www.ddddd.sk",
"http://www.wwwww.sk",
"http://www.ffffffff.sk"
],
"phones": [
"123456789",
"987456321",
"852147963"
],
"emails": [
"ccc#cccccc.sk",
"ggggggg#vggggg.sk",
"qqqqqqq#qqqqq.sk",
"sssssssss#sssss.sk",
"nadacia#volkswagen.sk",
"vvvvvv#vvvvvvv.sk",
]
},
From the ES documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/array.html
In Elasticsearch, there is no dedicated array type. Any field can
contain zero or more values by default, however, all values in the
array must be of the same datatype.
Background
I am making a form using http://schemaform.io/
Setup
I am trying to make an array of objects that a user can make using a form. So, the user can add as many items into the array as they want.
The array of items contains a type, then another field depending on what the type was.
If the user clicks REST, I want it to offer a field called method.
If the user clicks SSH, I want it to offer a field called path.
Code so far
SCHEMA
{
"type": "object",
"title": "Command Asset",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"commands": {
"type": "array",
"title": "Actions",
"items": {
"type": "object",
"properties": {
"commandType": {
"title": "Command Type",
"type": "string",
"enum": [
"REST",
"SSH"
]
},
"path": {
"title": "Path",
"type": "string"
},
"method": {
"title": "Method",
"type": "string"
}
}
}
}
}
}
FORM
[
{
"type": "help",
"helpvalue": "<h5>Command</h5>"
},
"name",
{
"title":"Command",
"key": "commands",
"items": [
"commands[].commandType",
{
"type": "conditional",
"condition": "modelData.commands[0].commandType=='SSH'",
"items": [
{
"key": "commands[].path"
}
]
},
{
"type": "conditional",
"condition": "modelData.commands[0].commandType=='REST'",
"items": [
{
"key": "commands[].method"
}
]
}
]
}
]
One can test this code here: http://schemaform.io/examples/bootstrap-example.html
Question
As one can see, the code I have now makes all the items' secondary properties (path or method) dependent on the first item in the array's commandType (at [0]), but I want it to depend on the commandType of the corresponding item. So, if item one has commandType of REST, it offers a method field and if item two has a command type of SSH it offers a field of path and so on.
I found an answer.
Replace the [0] with [arrayIndex].
I found it from here: https://github.com/json-schema-form/angular-schema-form/commit/21f6d3ab64435b032456dfe19e03f96b29366320