Nav
You are viewing an older version of this section. Click here to navigate to the latest version.

Mapping Elements Inside Lists

Use Anypoint DataMapper Transformer to map elements within a collection on a message payload.

A collection groups data items together in one message payload. Mule can split collections - such as lists or arrays - into individual elements to transform, or otherwise process them. For example, you can use Mule to map the data format of elements in a collection from a Java object to XML. However, rather than use a Splitter, a Transformer, and an Aggregator to map the data, you use one DataMapper Transfomer.

Anypoint DataMapper can map a collection in various ways to produce output data in any of six formats:

  • it can map a collection to a "flat" file, such as CSV

  • it can map a collection to a collection

  • it can map elements in a collection to a flat file, or to elements in another collection

  • it can map a nested collection (i.e., a collection within a collection) to another nested collection

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.

This document uses two examples to demonstrate how to map elements inside a list:

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 DataMapper to a flow

  4. Mapping the data

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

Creating the Sample XML Input File

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

    
                 
              
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    <contact_list type="members" id="id0">
      <contacts>
        <user name="John" lastname="Doe" phone="1111 1111"/>
        <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:

    
                 
              
    1
    
    Name,Lastname,Phone
  2. Save the file in a convenient location under a useful name, such as OutputList.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 Transformer Reference.

  1. From the Transformer group in the Palette, drag a DataMapper building block to any location in your flow, except to the left of the flow’s message source.

  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 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 field 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 file output file you created.

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

    image

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 that for each nested element in contact_list, you can create an entry in csv. In other words, you can map each nested element in contact_list to csv.

The Output pane on the right-hand side displays a list on output elements. The first item is the csv output file. In this case, there are no nested lists since the output format is a flat.

Mapping the Data

  1. Click the "closed eye" icon (see below, top) in the Input pane to reveal the individual elements in the lists. The two nested list in the XML file, contacts and emergency_contacts, display their respective chid elements (below,bottom).

    TOP
    BOTTOM
  2. Hover your mouse over an Input Attribute, identifiable by a blue "e" icon. Mule displays a tooltip specifying which elements in the Output Pane you can map the attribute to.

    3-1
  3. Click, then drag the user : userType element from the input pane to the csv root element in the output pane to map the emergency_contacts nested list. (Because the CSV output file in this example cannot contain nested lists, you can only drag an input attribute to the root node in the output pane.)

    image
  4. Click, then drag an individual child element in the emergency_contacts list to an individual element in the csv output. For example, drag the input elements name : string onto the output element Name : string.

  5. Repeat the previous steps to map many input elements to output elements. See the image below for an example.

    5-1

    In the image above, Mule maps each key in the emergency_contacts nested list to its corresponding value in the csv output mapping. The other nested list in the input XML file - contacts - is not mapped. As a result of the emergency_contacts mapping, the CSV output includes only the key-value pairs for the emergency_contacts list (see below).

    
                 
              
    1
    2
    3
    
    Larry,Larson,4444 4444
    Harry,Harrison,5555 5555
    John,Johnson,6666 6666
Consult Obtaining a Preview of Mapped Data to learn how to generate a preview of your mapping.

Mapping Nested Lists to Objects (XML to JSON)

In this example, Mule maps data from XML to JSON. The latter supports data structures and associative arrays.

Creating the Sample XML Input File

If you haven’t already created a sample XML file, complete the steps procedure above.

Creating the Sample JSON Output File

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

    
                 
              
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    {
      "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

Mapping the Data

  1. Click the "closed 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).

    image

    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, the drag the user : UserType element in the input pane to the emergencyContacts element in the output pane.

    DataMapper automatically maps all child elements for which it can find a match (see image below).

    image

    In the image above, notice that the DataMapper mapped name and lastname, but not phone. This is because the sample JSON file does not contain a child element, or key, called phone.

  3. Create a new key for phone, then map the input element to the output element.

    image

    Add a New Key (Field)

When mapping inside lists, DataMapper displays the current mapping level in the Current Element Mapping drop-down menu between the input and output panes. Use this menu to switch between all levels of mapping. DataMapper automatically adds new levels of mapping as you create them. In this example above, there are two items in the drop-down menu: contact_list_to_object and user_to_emergencyContacts (see image below).

image

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:


          
       
1
2
3
4
{
  "type" : "members",
  "id" : "id0",
[...]
  1. Click the contacts input attribute, then drag it to the contacts output attributes to map the nested contacts list (see image below).

    image
  2. DataMapper automatically adds a new mapping to the Current Element Mapping drop-down menu; note that it contains: user_to_contacts (below).

    image
  3. Under the contacts element in the output pane, create a new key for phone, then map the input element phone to this output element.

At this point, you have mapped all of the XML input fields to their corresponding JSON output fields. The DataMapper view should look like the image below. In this image, the top-level mapping user_to_contacts is selected, allowing you to see all mappings simultaneously. The arrows for the child mapping levels contact_list_to_object and user_to_emergencyContacts appear grayed-out.

image

The output of the mapping should be the following:


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "type" : "members",
  "id" : "id0",
  "contacts" : [ {
    "name" : "John",
    "lastname" : "Doe",
    "phone" : "1111 1111"
  }, {
    "name" : "Jane",
    "lastname" : "Doe",
    "phone" : "2222 2222"
  }, {
    "name" : "Harry",
    "lastname" : "Hausen",
    "phone" : "3333 3333"
  } ],
  "emergencyContacts" : [ {
    "name" : "Larry",
    "lastname" : "Larson",
    "phone" : "4444 4444"
  }, {
    "name" : "Harry",
    "lastname" : "Harrison",
    "phone" : "5555 5555"
  }, {
    "name" : "John",
    "lastname" : "Johnson",
    "phone" : "6666 6666"
  } ]
}
To generate a preview of your mapping, click the Preview tab in the DataMapper view, then click Run Mapping. Consult Obtaining a Preview of Mapped Data for details.