How Do I Map a Flat Structure Containing Both Header and Line Records to a Hierarchical XML? (Magic xpi 4.7)
When working with the Data Mapper in Magic xpi, you might find yourself in a situation where you need to map a flat structure to a hierarchical XML file.
Mapping a flat structure to a hierarchical XML file:
After you have dragged a Data Mapper into the Studio’s flow area, the first thing you need to do is to configure the Data Mapper’s Source properties, as follows:
-
From the Toolbox's Mapper Schemas section, drag an XML type into the Source area of the Data Mapper window.
-
In the XML Source's Properties pane, select the required XSD file (in this case, Accounts.xsd).
-
You need to define where you will take the data from, which, in this case, is a file called Accounts.xml. In the Source Type parameter, select File from the drop-down list.
-
In the File Path parameter, click to open the Expression Editor. Enter the following expression: EnvVal ('currentprojectdir')&'Data/Accounts.xml'
This expression tells the Source to look for a data file called Accounts.xml in the current project directory.
-
Click OK to close the Expression Editor.
After you have finished configuring the Data Mapper’s Source properties, you need to configure the Destination properties, as follows:
-
From the Toolbox's Mapper Schemas section, drag an XML type into the Destination area of the Data Mapper window.
-
In the XML Destination's Properties pane, select the required XSD file (in this case, Accounts1.xsd).
-
In the Destination Type parameter, select Variable from the drop-down list. Click and select C.UserBlob. This is where the mapped data will be sent to.
Now, to get a clearer picture of the data, let’s take a closer look at the structures of the Accounts.xsd and the Accounts1.xsd files as displayed in the Data Mapper window. To do this, park on the Source and on the Destination in the Data Mapper window, right-click on them, and select Expand All from the context menu.
In the Source pane (as shown below, left), you can see a flat structure defined by the contents of the Accounts.xsd file. This comprises a compound node called Account, which is made up of Name and ID nodes. In addition, there is a sibling compound node called PhoneNumber, which is made up of primary, value and accountID nodes.
Note that there is no parent-child relationship between the two compound nodes. The only connection between them is via the ID node and the accountID node.
In the Destination pane (as shown below, right), you can see a hierarchical parent-child structure defined by the Accounts1.xsd file. This comprises a parent compound node called Account, which is made up of Name and ID nodes. In addition, there is a child compound node called PhoneNumber, which is made up of primary and value nodes. In this case, the accountID node is unnecessary because the relationship between the accounts and their phone numbers is governed by the structure of the schema.
Next, you need to map the Source data to the Destination data, as follows:
-
In the Source pane, right-click on the Name node and select Connect. Then drag the mouse to the Name node in the Destination pane, and click.
-
In the Source pane, right-click on the ID node and select Connect. Then drag the mouse to the ID node in the Destination pane, and click.
-
In the Source pane, right-click on the primary node and select Connect. Then drag the mouse to the primary node in the Destination pane, and click.
-
In the Source pane, right-click on the value node and select Connect. Then drag the mouse to the value node in the Destination pane, and click.
The problem with this mapping is that each account will then hold the phone numbers of all the other accounts in addition to its own phone number. This happens because no filters have been applied to the mapping. To prevent this from happening, you should create the required filters:
-
Open the Flow Variables repository and create a flow variable called F.accountID.
-
To make sure that each account holds only its own phone number and not any others, you should use the Compound Level Computation mechanism. To do this, right-click on the AccountsRecords compound node in the Destination pane and select Show Properties.
-
In the Properties pane's Multi Updates parameter, click to open the Multi Updates dialog box. Here, click Add to create a new line.
-
In the Variable Name column, click and select your F.accountID variable.
-
In the Expression column, click to open the Expression Editor. Click and select the correct path for the ID node from the list.
The result of this expression is that, on the Source side, each iteration of the Accounts is given the value of the ID field.
Next, you need to filter the Source’s PhoneNumber records so that only those records with the same ID as the Destination’s Account will be sent to the child PhoneNumber record under that specific account:
-
Right-click on the PhoneNumber compound node in the Destination pane and select Show Properties.
-
In the Properties pane's Condition parameter, click to open the Expression Editor. Click and select the correct path for the accountID node from the list.
Note that F.accountID is the flow variable that you created earlier for the purpose of holding the account’s ID.
-
Click Save.
-
Set a breakpoint, and then debug the flow by right-clicking on the flow in the Solution Explorer and selecting Debug.
-
Run your project by clicking the Run/Continue Project button on the toolbar.
-
Click the Context View button on the toolbar to open the Context View window.
-
Here, select the Context Variable tab and look in the Name column for the C.UserBlob variable. Remember that you previously selected this variable in the Destination Properties dialog box’s Data Destination parameter to hold the results data. Click to zoom to the BLOB’s content.
-
In the View Variable: C.UserBlob window, select TXT from the drop-down list and click Open to see the actual XML file that you just created.
-
In the ContextView_BLOB.TXT XML file, you can see that each account has its own dedicated phone numbers listed underneath the account’s entry.
This XML was created in the following way:
-
For each Source Account element, an Account element was created in the Destination pane.
-
After that, the PhoneNumber elements were created in the Destination pane.
-
The phone numbers were then assigned to the accounts.
-
However, the filter that you created only mapped those phone numbers that matched the account ID to the Destination elements. This means that each account received only its own phone number(s), and not all the numbers contained in the Source file.