JSON Wizard makes it easy to modify and process any type of JSON in an Enfocus Switch environment.
Whether you want to:
-- all this is possible with a little JSON magic
Switch Fall 2022 and higher.
Use one of our sample flows and drop a sample file into the flow.
Compare the input JSON with the output JSON and checkout the executed actions.
This app requires one incoming connection - more incoming connections are allowed. The app supports traffic light outgoing connections of the following types:
Property | Value | Description |
---|---|---|
Working mode | enum [ JSON-File | JSON-Dataset | External JSON-File ] | |
Actions | String[] | A list of actions that should be executed. Go to Actions Syntax |
Set private data | String[] | Allows to set private data using a JSON Path expression of the resulting JSON; e.g.: myOrderID=$..[0].OrderID |
Additional datasets | String[] | The content of the dataset will be added to the master JSON and can be accessed by a JSONPATH expression like $... The added objects will be removed after all queries are done. |
Additional file | String | Allows to define an additional JSON file which will be appended to the master JSON. This can be useful if information from this file must be retrieved.The added objects will be removed after all queries are done. |
Object name | String | Defines the name of the appended object of the additional file. |
JSON-Dataset
Property | Value | Description |
---|---|---|
Master dataset name | String | Name of the dataset that should be processed |
External JSON-File
Property | Value | Description |
---|---|---|
File path | String | Path to external JSON file |
Delete after injection | Boolean | Defines if the external file should be deleted or not after it is injected as Switch job |
Append as dataset | Boolean | Defines if the JSON should be appended as dataset to the incoming job |
Dataset name | String | If Append as Dataset = true ; the dataset name of the JSON |
Job name | String | Default: The name proper of the incoming job; If Append as Dataset = false ; the name of the injected job. |
Comment: //
at the beginning of a line
Separator: ||
Actions
+
=> Creates new key-value pairs in objects or arrays; pushes new elements to array.&
=> Changes values of existing keys in objects or arrays-
=> Removes key-value pairs; removes elements from array?
=> Combines the functionality of Create and Update
JSONPath: A valid JSONPath expression; we recommend using https://jsonpath.com/ to test your queries; checkout https://www.npmjs.com/package/jsonpath and https://www.npmjs.com/package/jsonpath-plus for more information
Data types: string|boolean|number|json|jsonata
Value:
In case of
DataType=json
a stringified json object/array, else any string (it will be parsed according the selectedDataType
).
The value can also define a
JSONPath
that queries the current JSON. In this case the value has to start with `$.
If
DataType=jsonata
the value has to define a valid JSONata expression, which can be tested by the JSON Exerciser: https://try.jsonata.org/
Example JSON:
{
"Account": {
"Account Name": "Firefly",
"Order": [
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2
},
{
"Product Name": "Trilby hat",
"ProductID": 858236
}
]
},
{
"OrderID": "order104",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 4
},
{
"ProductID": 345664,
"Product Name": "Cloak",
"Quantity": 1
}
]
}
]
}
}
Configuration
+||$..[?(@.OrderID==\\'order103\\')]||string||myValue||Test
Result
The search query returns the object of the Order
collection, where the OrderID='order103'
.
For this object the key-value pair Test:"myValue"
will be set if the key does not exist.
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2
},
{
"Product Name": "Trilby hat",
"ProductID": 858236
}
],
"Test": "myValue"
}
Configuration
+||$..[?(@.OrderID=="order103")].Product||string||myValue||Test
Result
The search query returns the all elements of the Products
collection of the order where OrderID='order103'
.
This configuration sets the key-value pair Test:"myValue"
in every element in the array.
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2,
"Test": "myValue"
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
"Test": "myValue"
}
]
}
Configuration
+||$..[?(@.OrderID=="order103")].Product||json||"{\"Product Name\":\"Bowler Hat\",\"ProductID\":858383,\"Quantity\":2}"
Result
The search query returns all elements of the Products
collection of the order where OrderID='order103'
.
If key
is not defined, the value will be pushed into the array.
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2
},
{
"Product Name": "Trilby hat",
"ProductID": 858236
},
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2
}
]
}
This example demonstrates the use of an external lookup JSON. For more complex requirements it may be necessary to use two or more JSON-Wizard elements in sequence to work with results from a former process.
Example JSON
{
"OrderID": "order103",
"Product": {
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2,
"Test": "myValue"
}
}
select this external JSON as Additional file
and use lookup as Object name
in Switch
"productDetails": [
{
"productId": 8588383,
"diameter": 41,
"unit": "mm",
"prices": [
{
"units": 1,
"unitPrice": 20,
"currency": "EUR"
},
{
"units": 5,
"unitPrice": 18,
"currency": "EUR"
}
]
},
{
…
}
]
Configuration
It is important to understand, that the value is a JSONata expression, compared to the JSONPath selector.
+||$.Product||jsonata||lookup.productDetails[productId = $$.Product.ProductID].$join([diameter.$string(),unit])||diameter
This Jsonata looks up the imported lookup
object to find the element where the productId
matches. It contatenates the found diameter
value as string with the unit
value.
+||$.Product||Product@$p.lookup.productDetails[productId = $p.ProductID].prices[$p.Quantity>= units ][-1].$join([unitPrice.$string()," ",currency])||price
This Jsonata looks up the imported lookup
object to find the element where the productId
matches and which also matches the ordered unit. It contatenates the found unitPrice
value as string with the currency
value. As this query may return more than one item we use [-1]
to select the top most element.
This example makes use of @ variables.
Result
The search query returns the found elements of the productDetails
collection for the given ProductID
and as them as additinal properties.
{
"OrderID": "order103",
"Product": {
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2,
"Test": "myValue",
"diameter": "41mm",
"price": "20 EUR"
}
}
Configuration
&||$.Account.Order[?(@.OrderID=="order104")].OrderID||string||myValue
or
&||$.Account.Order[?(@.OrderID=="order104")]||string||myValue||OrderID
Result
The search query returns the OrderID
of the Order
with OrderID='order104
.
For this object the key OrderID
will be set to "myValue"
{
"OrderID": "myValue",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 4,
},
{
"Product Name": "Cloak",
"ProductID": 345664,
"Quantity": 1,
}
]
}
Configuration
&||$..[?(@.OrderID=="order104")].Product||number||100||Quantity
Result
The search query returns the Product
array of the Order
with OrderID='order103
.
For the elements in the array key Quantity
will be set to 100
if it exists.
{
"OrderID": "order104",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 100
},
{
"ProductID": 345664,
"Product Name": "Cloak",
"Quantity": 100
}
]
}
Configuration
&||$..[?(@.OrderID=="order103")].Product[0]||json||100||{\"myTest\":{\"x\":1}}
Result
The search query returns first element of the Product
array of the Order
with OrderID='order103
.
If the property key
is not defined, the element will be replaced by the defined value
.
{
"OrderID": "order103",
"Product": [
{
"myTest": {
"x": 1,
}
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
}
]
}
Configuration
?||$..[?(@.OrderID=="order103")].Product||number||100|Quantity
Result
The search query returns the Product
array of the Order
with OrderID='order103
.
For the elements in the array the key Quantity
will be set to 100
.
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 100
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
"Quantity": 100
}
]
}
Configuration
?||$.Account.Order[[?(@.OrderID=="order103")].Product||json||[[{"id":"1","Product Name":"MyNewProduct XY","ProductID":858383},{"id":"2","Product Name":"MyNewProduct Q","ProductID":858383}]
Result
The search query returns the Product
array of the Order
with OrderID='order103
.
For the elements in the array the app checks if a product with the same id
or key
already exists and if so it will update the element in the array. Otherwise the element will be pushed to the array.
The sample JSON did not contain any Products
with the an id, so the elements of the input array are pushed into the array.
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2
},
{
"Product Name": "Trilby hat",
"ProductID": 858236
},
{
"id": "1",
"Product Name": "MyNewProduct XY",
"ProductID": 858383
},
{
"id": "2",
"Product Name": "MyNewProduct Q",
"ProductID": 858383
}
]
}
Configuration
-||$.Account.Order[?(@.OrderID=="order104")].OrderID"
Result
The search query returns the OrderID
of the Order
with OrderID='order104
.
The key OrderID
will be removed from the order object.
{
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 4
},
{
"Product Name": "Cloak",
"ProductID": 345664,
"Quantity": 1
}
]
}
Configuration
-||$..[?(@.OrderID=="order104")].Product..Quantity
Result
The search query returns the Quantity
of the Product
array of the Order
with OrderID='order104
.
The key Quantity
will be removed from every element in the array.
{
"OrderID": "order104",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383
},
{
"Product Name": "Cloak",
"ProductID": 345664
}
]
}
Configuration
-||$..[?(@.OrderID=="order104")].Product[0]"
Result
The search query returns the first element of the Product
array of the Order
with OrderID='order104
.
The element will be removed from the array.
{
"OrderID": "order104",
"Product": [
{
"Product Name": "Cloak",
"ProductID": 345664
}
]
}
Allows to define a fallback query / value if the regular query does not return a value.
The regular query and the fallback query must be separated by ## as follows:
Synthax: <regular query>##<fallback>
In this case the property orientation
should be 'Landscape' if the object has no such property.
Otherwise if the property exists, the value should be unchanged
{
"device": "inline",
"gutterGap": 10,
"height": 297,
"nUp": 1,
"sheetSize": {
"height": 320,
"width": 460
},
"width": 210,
}
Configuration
JSONata:
?||$||jsonata||orientation##"Landscape"||orientation
JSONPath:
?||$||string||$.orientation##Landscape||orientation
Result
{
"device": "inline",
"gutterGap": 10,
"height": 297,
"nUp": 1,
"sheetSize": {
"height": 320,
"width": 460
},
"width": 210,
"orientation": "Landscape"
}
In that case the property secondProductHasQuantity
should be set to true or false. The JSONPath selects the order and the jsonata makes use of this result in it's query as currentElement
The currentElement
is removed from the resulting JSON at the end of every query.
The input JSON is the example JSON from above.
Configuration
+||$.Account.Order[?(@.OrderID=="order103")]||jsonata||$length($string(currentElement.Product[1].Quantity)) > 0 ? true : false||secondProductHasQuantity
+||$.Account.Order[?(@.OrderID=="order104")]||jsonata||$length($string(currentElement.Product[1].Quantity)) > 0 ? true : false||secondProductHasQuantity
JSON during runtime
first query:
{
"Account": {
"Account Name": "Firefly",
"Order": [...],
},
"currentElement": {
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2,
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
},
]
}
}
second query:
{
"Account": {
"Account Name": "Firefly",
"Order": [...],
},
"currentElement": {
"OrderID": "order104",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 4,
},
{
"Product Name": "Cloak",
"ProductID": 345664,
"Quantity": 1,
},
]
}
}
Result
{
"Account": {
"Account Name": "Firefly",
"Order": [
{
"OrderID": "order103",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 2,
},
{
"Product Name": "Trilby hat",
"ProductID": 858236,
},
],
"secondProductHasQuantity": false,
},
{
"OrderID": "order104",
"Product": [
{
"Product Name": "Bowler Hat",
"ProductID": 858383,
"Quantity": 4,
},
{
"Product Name": "Cloak",
"ProductID": 345664,
"Quantity": 1,
},
],
"secondProductHasQuantity": true,
},
],
},
}
This app uses two types of errors:
The following private data tags will be set if an error occurs:
Tag | Value | Type | Description |
---|---|---|
lastErrorElement | String | The name of the flow element |
lastErrorId | jsonWizardError | |
lastErrorCode | Number | an error code that defines the type of error that occured |
lastErrorMessage | String | detailed error message |
Error Codes:
enum ERROR_CODES {
generalError = 0,
fileHandlingError = 1,
fileFormatError = 2,
conversionError = 3,
invalidParameterValue = 4,
parsingError = 5,
}