<contact_list type="members" id="id0">
<contacts>
<user name="John" lastname="Harrison" phone="2013 0517"/>
<user name="Jane" lastname="Doe" phone="2222 2222"/>
<user name="Harry" lastname="Hausen" phone="3333 3333"/>
</contacts>
<emergency_contacts>
<user name="Larry" lastname="Larson" phone="4444 4444"/>
<user name="Harry" lastname="Harrison" phone="5555 5555"/>
<user name="John" lastname="Johnson" phone="6666 6666"/>
</emergency_contacts>
</contact_list>
Mapping Elements Inside Lists
Mule Runtime Engine versions 3.5, 3.6, and 3.7 reached End of Life on or before January 25, 2020. For more information, contact your Customer Success Manager to determine how you can migrate to the latest Mule version. |
A [collection] groups data items together in one message payload. Anypoint DataMapper supports complex mapping and transformation operations, including those where the input and output are complex nested structures of different data formats.
Before mapping elements in a list, you must first map the list itself to an output object or list. Once the input list maps to the output object or list, you can map its individual child elements.
Creating a series of element mappings that map input lists to output lists, and then map their child elements, you can ultimately map data elements at any level in complex structures, working your way down through nesting levels in the input and the output.
This document uses two examples to demonstrate how to map elements inside lists:
-
[Mapping Nested Lists to a Flat File (XML to CSV)]
-
[Mapping Nested Lists to a Structured Data File (XML to JSON)]
Both examples require sequential completion of the following high-level tasks:
-
Creating the sample input file.
-
Creating the sample output file.
-
Adding Anypoint DataMapper to a flow.
-
Mapping the data.
Mapping Nested List to a Flat File Format
Creating the Sample XML Input File
-
Create a new text file in a text editor, then paste into it the following contents:
-
Save the file to a convenient location under a useful descriptive name, such as
InputList.xml
. This serves as the input XML file for both examples.
Creating the Sample CSV Output File
-
Create another next text file, then paste into it the following contents:
Name,Lastname,Phone
-
Save the file in a convenient location under a useful name, such as
Output.csv
. This simple CSV file provides DataMapper with the output data fields. You can modify these fields when configuring the DataMapper building block.
Adding Data Mapper to a Flow
The following procedure offers abbreviated steps for adding a DataMapper to a flow. For detailed instructions, consult the DataMapper User Guide and Reference.
-
From the Transformer group in the Palette, drag a DataMapper building block to the location where it can receive its input - such as to the right of a File connector.
-
Click the DataMapper icon to open its Properties Editor.
-
In the Name field, type a useful, descriptive name for your DataMapper.
-
In the Input section of the Select Input and Output Type pane, use the drop-down menu next to the Type field to select XML.
-
In the Output section of the Select Input and Output Type window, use the drop-down menu next to the Type field to select CSV.
-
In the Output section, click the ellipsis (…) next to the CSV example field.
-
Use the file browser to select the CSV output file you created.
-
Click Create Mapping to load the configuration into the DataMapper Console (see image below)
The Element Mapping selector (center) shows the initial element mapping For Each 'contact_list' → 'output'
.
The Input pane on the left-hand side displays the input XML file’s root element, contact_list
. A dotted line connects contact_list
to csv
root element in the Output pane. This dotted line indicates that for each nested element in contact list
that is mapped in a child element mapping, DataMapper should create an entry in csv
.
The Output pane on the right-hand side displays a list of output elements. The top item represents the csv
output file, which can be understood as a list of rows, each of which contains the individual fields Name, LastName, and Phone. In this case, there are no nested lists in the output, since the output format is flat.
Mapping the Data
-
Click the "eye" icon (see below, top) in the Input pane to reveal the individual elements in the lists. The two nested lists in the XML file,
contacts
andemergency_contacts
, display their respective child element (below bottom). -
Hover your mouse over an input attribute, identifiable by a blue "e" icon. Mule displays a tooltip hinting which elements in the output pane you can map the attribute to.
-
Click, then drag the
user : UserType
element from the input pane to thecsv
root element in the output pane. The effects are:-
A new element mapping
Foreach 'user' → 'csv'
is created that maps theemergency_contacts/user
nested list to the CSV root element. -
Automapping maps all the individual fields under
user
to fields with matching names in the CSV. -
The DataMapper displays all the arrows reflecting these new mappings.
-
Note that the other nested list in the input XML file - contacts
- also shows a user element, but this one is not mapped.
To preview the behavior of the mapping without running your entire mapping flow, click Preview above the output pane:
For Input Data, enter the path to your sample input XML file, and then click Run to view the output.
Larry,Larson,4444 4444
Harry,Harrison,5555 5555
John,Johnson,6666 6666
As a result of the emergency_contacts
mapping, the CSV output includes rows corresponding to the emergency_contacts
list. There is no mapping for the ordinary contacts
element, so there is no output for those user
element in the CSV.
Consult [Previewing DataMapper Results on Sample Data] to learn about generating a preview of your mapping. |
Mapping Nested XML Lists to Nested JSON List
In this example, Mule maps data from XML to JSON. The latter supports simple data structures and associative arrays (which use keys and values roughly as XML uses attribute names and attribute values). This example shows how one representation of structured data can be converted to another.
Creating the Sample XML Input File
If you haven’t already created a sample XML file, complete the steps in the [procedure above].
Creating the Sample JSON Output File
-
Create a new file in a text editor, then paste into it the following contents:
{ "type": "members", "id": "id0", "contacts": [ { "name": "", "lastname": "" }, { "name": "", "lastname": "" }, ], "emergencyContacts": [ { "name": "", "lastname": "" }, ] }
-
Save the file to a convenient location under a useful descriptive name. This JSON file provides DataMapper with the output data fields.
Add DataMapper to a Flow
-
Follow steps 1 - 7 of the Add DataMapper to a Flow procedure in the previous example. (If you’ve completed the previous example, the DataMapper wizard asks if you want to overwrite the XML schema file. It is safe to overwrite it; click Ok.)
-
In the Output section of the Select Input and Output Type window, use the drop-down menu next to the Type field to select JSON.
-
In the Output section, click the ellipsis symbol (…) next to the JSON sample field.
-
Use the file browser to select JSON file you created.
-
Click Finish to load the configurations into the DataMapper Console (see image below)
Mapping the Data
-
Click the "eye" icon in the Input pane or the Output pane to display child elements in the XML lists and JSON objects respectively (see image below).
In the screenshot above, the Output mapping pane contains two nested lists:
contacts
andemergencyContacts
. Mule read the names of these lists from the sample JSON file.Note that the child element of each list - both in the input pane and in the output pane - are greyed out. Before you can map individual list elements to each other, you must first map the list (displayed in bold type) themselves.
-
Click, then drag the
user : user
element underemergencyContacts
in the input pane to theemergencyContacts:emergencyContacts
element int he output pane.The effects of doing so are:
-
A new element mapping is created, mapping the
emergency_contact/user
list in the XML input to theobject/emergencyContracts
list in the JSON output; -
DataMapper auto-maps all children of
emergency_contacts/user
that have matching names to children ofemergencyContacts
-
-
Notice that the DataMapper mapped
name
andlastname
but notphone
. The sample JSON file does not contain a field or attribute calledphone
. To include phone numbers for the emergency contacts, create a new attribute forphone
, then drag and drop to map the phone input attribute to the new output attribute.Add a New Metadata Field
Complete the following steps to create the new field in the output pane.
-
In the output pane, right-click the
emergencyContacts
list, then select Add Metadata Field. -
Fill in the New Attribute dialog:
-
For Type, select Attribute.
-
For Name field on the New Attribute window, type the name of the attribute.
-
For Configuration → Type select string.
-
-
Click Ok. The new
phone
attribute is created in the JSON output file. -
Click the
phone
element in the input pane, then drag it to newly-createdphone
key in the output pane.
-
-
The next step is to map the
contacts
element in the XML to its counterpart in the JSON.In order to map the
contacts
item, first we must select the element mapping between their parents - theForEach 'contact_list' to 'object'
element mapping. Use the Element Mapping control to make this selection:The mapping editor updates to focus on this mapping:
Data Mapper automatically created the top level - contact_list_to_object - when you completed the configuration in the DataMapper wizard. This level maps the XML input file
<contact_list_type='members' id='id0'>
to the JSON output file:{ "type" : "members", "id" : "id0", [...] }
Click the
contacts/user
list, then drag it to thecontacts
output list to map these elements:The effects are:
-
DataMapper adds a
newForEach 'user' → 'contacts'
mapping to the Element Mapping drop-down menu; -
The input attributes in
'user'
are automapped to the matching output fields in'contacts'
At this point you have mapped all XML input fields to their corresponding JSON output fields. The final DataMapper view should look like the image below. You can check each of the element mappings to see if they match.
The output of the mapping should be following:
{ "type" : "members", "id" : "id0", "emergencyContacts" : [ { "name" : "Larry", "lastname" : "Larson", "phone" : "4444 4444" }, { "name" : "Harry", "lastname" : "Harrison", "phone" : "5555 5555" }, { "name" : "John", "lastname" : "Johnson", "phone" : "6666 6666" } ], "contacts" : [ { "name" : "John", "lastname" : "Harrison" }, { "name" : "Jane", "lastname" : "Doe" }, { "name" : "Harry", "lastname" : "Hausen" } ] }
To generate a preview of your mapping, click the Preview tab in the DataMapper view, then click Run Mapping. Consult [Previewing DataMapper Results on Sample Data] for details.
-