Contact Us 1-800-596-4880

Mapping Elements Inside Lists

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:

  1. Creating the sample input file

  2. Creating the sample output file

  3. Adding Anypoint DataMapper to a flow

  4. Mapping the data

Mapping Nested Lists to a Flat File Format (XML to CSV)

Creating the Sample XML Input File

  1. Create a new text file in a text editor, then paste into it the following contents:

    <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>
  2. 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

  1. Create another new text file, then paste into it the following contents:

    Name,Lastname,Phone
  2. 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.

  1. From the Transformers 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 endpoint..

  2. Double-click the DataMapper to open its configuration wizard.

  3. In the Name field, type a useful, descriptive name for your DataMapper, then click Next.

  4. In the Input section of the the Select Input and Output Type pane, use the drop-down menu next to the Type field to select XML.

  5. Click Generate schema from xml, then use the file browser to select the XML input file you created. Click OK.

  6. 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.

  7. In the Output section, click the ellipsis (…​) next to the CSV example field.

  8. Use the file browser to select the CSV output file you created.

  9. Click Finish to load the configurations into the Data Mapping Editor (see image below).

    image::image2013-4-16-143a43a59.png[image2013-4-16+14:4:59]
    The Element Mapping selector (center) shows the initial element mapping, ForEach '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 the 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

  1. 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 and emergency_contacts, display their respective child elements (below, bottom).

    image::image2013-4-16-14a9a32.png[image2013-4-16+14:9:32]
    image2013-4-16+14:33:18

  2. 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.

    image::image2013-4-16-14a36a47.png[image2013-4-16+14:36:47]

  3. Click, then drag the user : userType element from the input pane to the `csv`root element in the output pane. The effects are:

    • A new element mapping Foreach 'user' → 'csv' is created that maps the emergency_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.

    image2013-4-16+14:41:27

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:

image2013-4-16+15:31:11

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`elements in the CSV.

Consult Previewing DataMapper Results on Sample Data to learn more about generating a preview of your mapping.

Mapping Nested XML Lists to Nested JSON Lists

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 Mapping Nested Lists to a Flat File Format (XML to CSV).

Creating the Sample JSON Output File

  1. 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": ""
        },
      ]
    }
  2. 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

  1. 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.)

  2. 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.

  3. In the Output section, click the ellipsis symbol (…​) next to the Json sample field.

  4. Use the file browser to select the JSON file you created.

  5. Click Finish to load the configurations into the Data Mapping Console (see image below).

    image::image2013-4-16-16a0a28.png[image2013-4-16+16:0:28]

Mapping the Data

  1. 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).

    image2013-4-16+16:15:44

    In the screenshot above, the Output mapping pane contains two nested lists: contacts and emergencyContacts. Mule read the names of these lists from the sample JSON file.
    Note that the child elements 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 lists (displayed in bold type) themselves.

  2. Click, then drag the user : user element under emergencyContacts in the input pane to the emergencyContacts: emergencyContacts element in the output pane.
    The effects of doing so are:

    • A new element mapping is created, mapping the emergency_contacts/user list in the XML input to the object/emergencyContacts list in the JSON output;

      image2013-4-16+17:19:44
    • DataMapper auto-maps all children of emergency_contacts/user that have matching names to children of emergencyContacts.

      image2013-4-16+16:17:16
  3. Notice that the DataMapper mapped name and lastname, but not phone. The sample JSON file does not contain a field or attribute called phone. To include phone numbers for the emergency contacts, create a new attribute for phone, 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.

    1. In the output pane, right-click the emergencyContacts list, then select Add Metadata Field.

      image2013-4-16+16:18:47
    2. Fill in the New Attribute dialog:

      • For Type, select Attribute.

      • For Name field of the New Attribute window, type the name of the attribute.

      • For Configuration → Type, select string.

      image2013-4-16+16:20:21
    3. Click OK. The new phone attribute is created in the JSON output file.

      image2013-4-16+16:21:3
    4. Click the phone element in the input pane, then drag it to the newly-created phone key in the output pane.

      image2013-4-16+16:22:33
  4. The next step is to map the contacts element in the XML to its counterpart in the JSON.

In order to map the contacts items, first we must select the element mapping between their parents-- the “ForEach 'contact_list' to 'object'” element mapping. Use the Element Mapping control to make this selection:

image2013-4-16+17:49:44

The mapping editor updates to focus on this mapping:

image2013-4-16+17:50:33

DataMapper 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 the `contacts`output list to map these elements:

image2013-4-16+17:53:12

The effects are:

  • DataMapper adds a new`ForEach '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 of the 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.

image2013-4-16+18:0:41

The output of the mapping should be the 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.