I have to build tree like structure of Json data.Each node has an id (an integer, required), a label (a string, optional), and an array of child nodes (optional). Can you help me how to write JSON schema for this Json data. I need to set Id as required in child node as well.
{
"Id": 1,
"Label": "A",
"Child": [
{
"Id": 2,
"Label": "B",
"Child": [
{
"Id": 5,
"Label": "E"
}, {
"Id": 6,
"Label": "E"
}, {
"Id": 7,
"Label": "E"
}
]
}, {
"Id": 3,
"Label": "C"
}, {
"Id": 4,
"Label": "D",
"Child": [
{
"Id": 8,
"Label": "H"
}, {
"Id": 9,
"Label": "I"
}
]
}
]
}
A schema for this structure only needs a definition of a node and a reference to that node. The property Children (renamed from Child) references the node as well.
Here's the schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#/definitions/node",
"definitions": {
"node": {
"properties": {
"Id": {
"type": "integer"
},
"Label": {
"type": "string"
},
"Children": {
"type": "array",
"items": {
"$ref": "#/definitions/node"
}
}
},
"required": [
"Id"
]
}
}
}
Related
I need to search for an XML Attribute Value, group it and form a corresponding JSON element.
Now for example: Label is my AttributeID and I have 2 attributes with Label.
(In realtime - it can be 'n' number of times.)
Need to group 2 Labels as a single JSON element.
VendorClass, VendorDivision and VendorDept should all come inside Vendor Json attribute.
VendorClass attributeValue should be mapped to classCode inside Vendor and other 2 codes should be null.
Likewise, VendorDept attributeValue should be mapped to DeptCode., VedorDivision attrbiuteValue mapped to DivisionCode.
O/P JSON (mapping):
type - should always be in upper characters - mapped to attributeID,
name - in lower character - mapped to "attributeId_attributeValue",
id/code - is attribute_value
Below is my i/p XML
<CurrentRule Currency="USD"
CurrentStatus="ACTIVE"
Priority="0"
RuleCategory="Current"
RuleType="COMBINATION"
>
<CurrentRuleTargetAttributeValueList/>
<CurrentRuleAttributeValueList>
<CurrentRuleAttributeValue
TriggerAttributeID="Label"
TriggerAttributeValue="10"/>
<CurrentRuleAttributeValue
TriggerAttributeID="Label"
TriggerAttributeValue="1003"/>
<CurrentRuleAttributeValue
TriggerAttributeID="ABCDCode"
TriggerAttributeValue="AC"/>
<CurrentRuleAttributeValue
TriggerAttributeID="ABCDCode"
TriggerAttributeValue="FD"/>
<CurrentRuleAttributeValue
TriggerAttributeID="VendorClass"
TriggerAttributeValue="00N"/>
<CurrentRuleAttributeValue
TriggerAttributeID="VendorDept"
TriggerAttributeValue="100"/>
<CurrentRuleAttributeValue
TriggerAttributeID="VendorDivision"
TriggerAttributeValue="10"/>
<CurrentRuleAttributeValue
TriggerAttributeID="VendorMarket"
TriggerAttributeValue="QVC"/>
<CurrentRuleAttributeValue
TriggerAttributeID="PriceCode"
TriggerAttributeValue="FP"/>
<CurrentRuleAttributeValue
TriggerAttributeID="ProductNumber"
TriggerAttributeValue="A0000"/>
<CurrentRuleAttributeValue
TriggerAttributeID="Trader"
TriggerAttributeValue="1010"/>
<CurrentRuleAttributeValue
TriggerAttributeID="Trader"
TriggerAttributeValue="1046"/>
</CurrentRuleAttributeValueList>
</CurrentRule>
Expected JSON o/p:
{
"header": {
"type": "ORDER",
"name": "merch-attribute-example",
"createUser": "admin"
},
"filters": {
"Labels": [
{
"type": "LABEL",
"name": "Label_10",
"LabelId": 10
},
{
"type": "LABEL",
"name": "Label_1003",
"LabelId": 1003
}
],
"vendor": [
{
"type": "VENDOR",
"name": "vendorclass_00n",
"divisionCode": null,
"departmentCode": null,
"classCode": "00N"
},
{
"type": "VENDOR",
"name": "vendordept_100",
"divisionCode": null,
"departmentCode": "100",
"classCode": null
},
{
"type": "VENDOR",
"name": "vendordivision_10",
"divisionCode": "10",
"departmentCode": null,
"classCode": null
}
],
"abcd": [
{
"type": "ABCD",
"name": "abcdcode_ac",
"abcdCode": "AC"
},
{
"type": "ABCD",
"name": "abcdcode_fd",
"abcdCode": "FD"
}
],
"priceCodes": [
{
"type": "PRICE_CODE",
"name": "pricecode_fp",
"code": "FP"
}
],
"products": [
{
"type": "PRODUCT",
"name": "productnumber_a0000",
"productNumbers": [
"A0000"
]
}
],
"traders": [
{
"type": "TRADER",
"name": "trader_1010",
"vendorCode": "1010"
},
{
"type": "TRADER",
"name": "trader_1046",
"vendorCode": "1046"
}
]
}
}
enter code here
Based on the rules described this is the best approximation. I'll leave to you how to decide if it is an id or code and the rest of the output that is not clearly explained.
%dw 2.0
output application/json
---
{
header: {
"type": "ORDER",
"name": "merch-attribute-example",
"createUser": "admin"
},
filters: payload.CurrentRule.CurrentRuleAttributeValueList
mapObject ((value, key, index) ->
{
attr: key.#
}
)
pluck (($$):$)
groupBy ((item, index) -> item.attr.TriggerAttributeID)
mapObject ((value1, key1, index1) ->
(key1): value1 map
{
"type": upper(key1),
name: lower(key1) ++ "_" ++ $.attr.TriggerAttributeValue,
id: $.attr.TriggerAttributeValue
}
)
}
Output:
{
"header": {
"type": "ORDER",
"name": "merch-attribute-example",
"createUser": "admin"
},
"filters": {
"Label": [
{
"type": "LABEL",
"name": "label_10",
"id": "10"
},
{
"type": "LABEL",
"name": "label_1003",
"id": "1003"
}
],
"ABCDCode": [
{
"type": "ABCDCODE",
"name": "abcdcode_AC",
"id": "AC"
},
{
"type": "ABCDCODE",
"name": "abcdcode_FD",
"id": "FD"
}
],
"VendorClass": [
{
"type": "VENDORCLASS",
"name": "vendorclass_00N",
"id": "00N"
}
],
"VendorDept": [
{
"type": "VENDORDEPT",
"name": "vendordept_100",
"id": "100"
}
],
"VendorDivision": [
{
"type": "VENDORDIVISION",
"name": "vendordivision_10",
"id": "10"
}
],
"VendorMarket": [
{
"type": "VENDORMARKET",
"name": "vendormarket_QVC",
"id": "QVC"
}
],
"PriceCode": [
{
"type": "PRICECODE",
"name": "pricecode_FP",
"id": "FP"
}
],
"ProductNumber": [
{
"type": "PRODUCTNUMBER",
"name": "productnumber_A0000",
"id": "A0000"
}
],
"Trader": [
{
"type": "TRADER",
"name": "trader_1010",
"id": "1010"
},
{
"type": "TRADER",
"name": "trader_1046",
"id": "1046"
}
]
}
}
The entire JSON file is rather large so I've only taken out the subsection I've had an issue with.
{
"diagrams": {
"5f759d15cd046720c28531dd": {
"_id": "5f759d15cd046720c28531dd",
"offsetX": 320,
"offsetY": 42,
"zoom": 80,
"modified": 1604279356,
"nodes": {
"5f9f5c3ccd046720c28531e4": {
"nodeID": "5f9f5c3ccd046720c28531e4",
"type": "start",
"coords": [
360,
120
],
"data": {
"name": "Start",
"color": "standard",
"ports": [
{
"type": "",
"target": "5f9f5c3ccd046720c28531e6"
}
],
"steps": []
}
},
"5f9f5c3ccd046720c28531e5": {
"nodeID": "5f9f5c3ccd046720c28531e5",
"type": "block",
"coords": [
760,
120
],
"data": {
"name": "Help Message",
"color": "standard",
"steps": [
"5f9f5c3ccd046720c28531e6",
"5f9f5c3ccd046720c28531e7"
]
}
},
"5f9f5c3ccd046720c28531e6": {
"nodeID": "5f9f5c3ccd046720c28531e6",
"type": "speak",
"data": {
"randomize": false,
"dialogs": [
{
"voice": "Alexa",
"content": "You said help. Do you want to continue?"
}
],
"ports": [
{
"type": "",
"target": "5f9f5c3ccd046720c28531e7"
}
]
}
},
"5f9f5c3ccd046720c28531e7": {
"nodeID": "5f9f5c3ccd046720c28531e7",
"type": "interaction",
"data": {
"name": "Choice",
"else": {
"type": "path",
"randomize": false,
"reprompts": []
},
"choices": [
{
"intent": "",
"mappings": []
},
{
"intent": "",
"mappings": []
}
],
"reprompt": null,
"ports": [
{
"type": "else",
"target": null
},
{
"type": "",
"target": null
},
{
"type": "",
"target": "5f9f5c3ccd046720c28531e9"
}
]
}
},
"5f9f5c3ccd046720c28531e8": {
"nodeID": "5f9f5c3ccd046720c28531e8",
"type": "block",
"coords": [
1170,
260
],
"data": {
"name": "Exit",
"color": "standard",
"steps": [
"5f9f5c3ccd046720c28531e9"
]
}
},
"5f9f5c3ccd046720c28531e9": {
"nodeID": "5f9f5c3ccd046720c28531e9",
"type": "exit",
"data": {
"ports": []
}
}
},
"children": [],
"creatorID": 42661,
"variables": [],
"name": "Help Flow",
"versionID": "5f759d15cd046720c28531db"
}
}
}
The Current JSON Schema Definition I have is:
{
"$schema":"http://json-schema.org/schema#",
"type":"object",
"properties":{
"diagrams":{
"type":"object"
}
},
"required":[
"diagrams",
]
}
The problem I am having is that within diagrams contains multiple objects with a random string as the name e.g "5f759d15cd046720c28531dd".
Then within that object there are properties such as (_id, offsetX) which I want to express as well as a nodes object, which again contains multiple objects with arbitrary names e.g ("5f9f5c3ccd046720c28531e4", "5f9f5c3ccd046720c28531e5", ...) which have a unique node definition where some nodes have different properties to other nodes (nodeID, type, data vs nodeID, type, data, coords).
My question is with all these arbitrary things such as random names as well as different properties per each node. How do I turn it into 1 JSON schema definition which covers all the cases of how a diagram/node can be made.
You can do this with additionalProperties or patternProperties.
additionalProperties applies to any property that isn't declared in properties or patternProperties.
{
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"_id": { ... },
"offsetX": { ... },
...
}
}
}
Your property names appear to always be hex numbers. If you want to enforce that those property names are always hex numbers, you can use patternProperties. Any property that matches the regex must conform to that schema.
{
"type": "object",
"patternProperties": {
"^[0-9a-f]{24}$": {
"type": "object",
"properties": {
"_id": { ... },
"offsetX": { ... },
...
}
}
},
"additionalProperties": false
}
i've log with thousands records of aggregated data in JSON:
{
"count": 25,
"domain": "domain.tld",
"geoips": {
"AU": 5,
"NZ": 20
},
"ips": {
"1.2.3.4": 5,
"1.2.3.5": 1,
"1.2.3.6": 1,
"1.2.3.7": 1,
"1.2.3.8": 1,
"1.2.3.9": 9,
"1.2.3.10": 7
},
"subdomains": {
"a.domain.tld": 1,
"b.domain.tld": 1,
"c.domain.tld": 1,
"domain.tld": 22
},
"tld": "tld",
"types": {
"1": 3,
"43": 22
}
}
and i have mapping on ES:
"mappings": {
"properties": {
"count": {
"type": "long"
},
"domain": {
"type": "keyword"
},
"ips": {
"type": "nested",
"properties": {
"key": {
"type": "keyword"
},
"val": {
"type": "long"
}
}
},
"geoips": {
"type": "nested",
"properties": {
"key": {
"type": "keyword"
},
"val": {
"type": "long"
}
}
},
"subdomains": {
"type": "nested",
"properties": {
"key": {
"type": "keyword"
},
"val": {
"type": "long"
}
}
},
"tld": {
"type": "keyword"
},
"types": {
"type": "nested",
"properties": {
"key": {
"type": "keyword"
},
"val": {
"type": "long"
}
}
}
}
}
Is there any simple way how import these lines to ES as nested objects ? If i use a bulk insert without modification, the ES will modify mapping by adding a new field for each IP/subdomain/GeoIP instead add it as simple key/val object.
Or only one way is regenerate JSON to key/val nested fields ?
Your mapping is already very good but the data doesn't fit it since the nested data type expects an array of objects, not a single object. So you'll need to transform your nested objects into array of key-value pairs like so:
...
"ips": [
{
"key": "1.2.3.4",
"val": 5
},
{
"key": "1.2.3.5",
"val": 1
},
...
],
"subdomains": [
{
"key": "a.domain.tld",
"val": 1
},
{
"key": "b.domain.tld",
"val": 1
},
...
]
...
I was trying to use an online fake data generator to generate sample data from my json schema but it did not accept my schema for some reason but I don't see anything wrong with it. I want to do it manually but I'm not sure if I did it correctly. Does the data below match the schema?
Schema
{
"$schema": "http://somesite.com",
"description": "mychema",
"type": "object",
"properties": {
"Form": {
"description": "form properties",
"type": "object",
"properties": {
"formproperty": {
"description": "test value",
"type": "string"
}
}
},
"FormElements": {
"description": "form elements and their properties",
"type": "array",
"items": {
"title": "Form Element",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier",
"type": "string"
},
"positionX": {
"description": "The X coordinate",
"type": "number"
},
"positionY": {
"description": "The Y coordinate",
"type": "number"
},
"elementSpecificProperties": {
"description": "unique properties",
"type": "object",
"oneOf": [
{ "$ref": "#/definitions/Label" }
]
}
}
}
}
},
"definitions": {
"Label": {
"type": "object",
"properties": {
"value": {
"description": "",
"type": "string"
}
}
}
}
}
Data
{
"Form":{
"formproperty": "test"
},
"FormElements":[
{
"id": "1",
"positionX": 20,
"positionY": 15,
"value": "testing1"
},
{
"id": "2",
"positionX": 5,
"positionY": 12,
"value": "testing2"
}
]
}
I can confirm that your schema is valid and that the data is valid against the schema. However, based on your schema, I think what you meant is this.
{
"Form": {
"formproperty": "test"
},
"FormElements": [
{
"id": "1",
"positionX": 20,
"positionY": 15,
"elementSpecificProperties": {
"value": "testing1"
}
},
{
"id": "2",
"positionX": 5,
"positionY": 12,
"elementSpecificProperties": {
"value": "testing2"
}
}
]
}
I am creating a JSON schema and want to define an array containing only exact matches for certain items:
An example of the sort of JSON (snippet) would look like:
{
"results":
[
{ "id": 1, "test": true, "volts": 700, "duration": 100 },
{ "id": 2, "test": false }
]
}
This seems to be a combination of OneOf and "additionalProperties": false but I can't work out how that should be used. So far I have:
{
"results":
{
"type": "array",
"items":
{
"type": "object",
"OneOf":
[
{
"id": { "type": "integer" },
"test": { "type": "boolean" },
"volts": { "type": "integer" },
"duration": { "type": "integer" }
},
{
"id": { "type": "integer" },
"test": { "type": "boolean" }
}
],
"additionalProperties": false
}
}
}
I'm using http://www.jsonschemavalidator.net/ to check my JSON.
But when I validate the following JSON against my schema it says it's valid; is the website incorrect or have I done something wrong?
{
"results": [
{
"fred": 7,
"id": 7,
"test": true,
"volts": 7,
"duration": 7
},
{
"fish": 7
}
]
}