Getting Started with DataWeave: Part 4

September 29 2015

21 comments
Getting started with dataweave part 4

In this final part of our introduction to DataWeave, we now present you with some example transformations. Just in case you missed the previous posts I included parts 1 to 3 below:

We will use everything we have learned till now to realize the transformations. Wherever we introduce new concepts we will highlight them in a subsequent set of notes. So, without further delay, let’s jump in!

Scenario 1

Google’s Address API responds with a JSON object which contains an array of addresses followed by their distances from our current location. We want to transform this into an array of the top 5 closest addresses.

Input

Screen Shot 2015-09-23 at 7.41.36 PM

Output

Screen Shot 2015-09-23 at 7.41.45 PM

Transformation

Screen Shot 2015-09-23 at 8.31.04 PM

Notes

  • The flatten operator transforms an array of arrays to a single array containing all of the elements in each of the nested arrays.
  • $$ is an alias for the the index of the current iteration through a.
  • d[$$] selects the element in whose index is $$. Dynamic key selection will also work on objects. Any expression which resolves to the name of the key can be used within square brackets.

Scenario 2

Given an Xml document with a sequence of line items, transform it to a JSON document with the field names slightly modified.

Input

Screen Shot 2015-09-23 at 7.26.36 PM

Output

Screen Shot 2015-09-23 at 7.37.26 PM

Transformation

Screen Shot 2015-09-24 at 8.07.48 AM

Notes

  • ‘$$_1’ allows us to dynamically build the value for the keys in our output by appending ‘_1’ to the key name present in the input.
  • mapObject is an operator that iterates through the key:value pairs on the input Value object and rather than produce an array, it simply builds another object defined by its right-hand operand.

Scenario 3

Given 2 responses to SOAP-based WebServices as input transform them into JSON object. The first Xml GetMedicationsResponse contains the medications for a patient. The second Xml GetMedicationsOrderResponse contains orders for the same medications. We need to iterate through each Medication in the first Xml and only produce output if the InternalId for the Medication is in the list of Orders and they Route code for the Order is oral (15) and the RefillsRemaining on the Order is greater than 1.

Input

Screen Shot 2015-09-23 at 7.42.20 PMScreen Shot 2015-09-23 at 7.42.30 PM

Output

Screen Shot 2015-09-23 at 7.42.40 PM

Transformation

Featured Image DataWeave 4

Notes

  • The %var global variable declaration allows us to use those variables anywhere in the transformation, including other global variable value assignments and function bodies.
  • The [?(<filter-criteria>)] expression allows us to filter on a key selector. There is a subtle difference between this mode of filtering and that of the filter operator. When no elements on the array match the criteria in this construct, then null is returned. Filter on the contrary will return an empty array.
  • The contains operator tests for the presence of a value in a container. The right-hand operand is the value. The left-hand operand is the container. This can be an array, a string or an object. When objects are tested, the container is actually the array of values in its sequence of key:value pairs. Here, we simply test arrays of strings for the presence of a string.

Scenario 4

Given a plain text sequence of identifiers, separated by the character ‘+’, and each of which may begin with a code containing 2 to 4 upper-case letters, output a JSON object whose keys are those same codes and whose values are arrays of the remaining part of each identifier which begins with the code. If any identifiers are found that don’t contain codes as specified, then these should be added to the array keyed by ‘invalid’ in the output.

Input

Screen Shot 2015-09-23 at 7.42.01 PM

Output

Screen Shot 2015-09-23 at 7.42.11 PM

Transformation

Screen Shot 2015-09-23 at 8.47.45 PM

Notes

  • The splitBy operator creates an array of the values resulting from those sequences of characters between each occurance of the splitting criteria specified as its right hand operand.
  • The match operator returns an array of matches that contains the entire matching expression, followed by all of the capture groups that match the provided regular expression. In this case ($ match /([A-Z]{2,4})\d*/)[1] will return the code which will be in the first and only capture  group for those identifiers it matches.
  • The default operator returns its right hand operand value when its left-hand operand returns null.
  • The pluck operator iterates through the key:value pairs on an object and builds an array of its values ($) or its keys ($$).

Scenario 5

Given an Xml document containing Stock quotes, transform it into a plain text sequence of characters with the <Values/> elements padded to 4 digits before and after the decimal, separating each Quote with a ‘~’ and terminating the SymbolId with a ‘*’.

Input

Screen Shot 2015-09-24 at 4.35.43 PM

Output

Screen Shot 2015-09-24 at 4.35.54 PM

Transformation

Screen Shot 2015-09-29 at 1.35.03 PM

Notes

  • The reduce operator iterates through an array and executes the lamda function you define as its right-hand operand. In this case we append each element quote to the accumulator qStr.

Scenario 6

Take the output from Scenario 6, the plain text string of codes and values and transform it back to the original input Xml from Scenario 5.

Input

Screen Shot 2015-09-24 at 4.35.54 PM

Output

Screen Shot 2015-09-24 at 4.35.43 PM

Transformation

Screen Shot 2015-09-25 at 2.44.57 PM

Notes

  • Here we necessarily cast each of the values to a number with two decimal places using the as operator. Thus we remove the padding zeros leading and trailing each value.

Further Reference

That’s it! We refer you to our documentation for an deep reference of the complete language as well as a tutorial to help you get started and a webinar with more a live demonstration and finally, some more examples.