You can use the For Each transform to iterate over one input array element, which can be either a simple type or a complex type repeating structure, and set the value of an output element.
The For Each transform contains a nested map. You must map the elements in the nested map, otherwise no action is executed when the transform runs.
You can configure the For Each transform to run when there are input elements that match your input selection criteria.
You can configure the For Each transform to execute once when the input array is empty by setting the Allow Empty input condition in the Filter Inputs property tab.
You can specify the indexes of the input array that participate in the For Each operation by setting the Cardinality property.
You can specify an XPath condition over the indexes that participate in the For Each operation by setting the Filter Inputs property. This condition determines which indexes are applied.
The Cardinality property determines the inputs that participate in the For Each operation.
The first index element is 1.
You configure the Cardinality tab in the Properties view to specify the indexes that are processed by the transform. For more information, see Selecting the indexes of input array elements.
Configure the Filter Inputs property tab to specify an XPath expression that determines which instances of the repeating input are processed in the nested mapping. Each element of the repeatable input is tested against the condition. The transform runs for those elements that satisfy the condition.
You can use XPath, or methods from Java™ classes to define the Filter Inputs expression. You can also create a complex expression comprising XPath and Java.
You can use context assist by pressing Ctrl+Space while you construct the Filter Inputs expression. For more information, see Using content assist (Mapping syntax).
Enable Allow Empty input when the input array element is empty or no inputs match a provided filter condition, so that the transform is still entered exactly once. In this case, the primary input in the nested transform is missing, and the index variable is zero.
The output element of a For Each transform can be a simple element, or a complex element, that can be a repeating element or a non-repeating element.
The output array size is equal to the input array size, minus any elements that are filtered out after applying the Cardinality and the Filter Inputs properties.
In the For Each transform, you can use the $VarName-index variable to indicate the index of the input array that the Graphical Data Mapping editor is processing.
For example, you might have an input array with 6 elements. When you set the Cardinality property of a For each transform to 1,3, you are telling the Graphical Data Mapping editor that you only want to process index 1 and index 3 of your input array. In this use case, the $VarName-index has a value of 1 for the first entry and a value of 3 for the second entry.
You can use the variable $VarName-index as part of the XPath condition that you can define to filter inputs, or as part of any transformation within the nested map that is associated to the For each transform.
The fist value of $VarName-index is 1 when your input array is not empty.
The value of $VarName-index is 0 when your input array is empty. You must enable the Allow Empty input property.
In the nested mapping of the For Each transform, you can use the $VarName-count variable to determine the number of times the Graphical Data Mapping editor enters the nested mapping to allow populating the output array.
The variable $VarName-count initial value is 1 . The maximum value is determined by the Cardinality and the Filter Inputs properties that are applied.
You cannot use the variable $VarName-count as part of the XPath condition that you can define to filter inputs.
You can use the variable $VarName-count as part of any transformation within the nested map that is associated to the For each transform.
The value of $VarName-count is 1 when you enable Allow Empty input in a For each transform and the nested mapping is entered as a result of the empty condition.
In this example, the For Each transform only runs for a restricted number of elements of the repeating element. The rest of the elements in the array are not considered.
The For Each transform iterates over instances 2, 3, and 4 between the input element stock and the output element inventory.
2:4
<?xml version="1.0" encoding="UTF-8"?>
<tns:Input xmlns:tns="http://www.example.org/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/schema foo.xsd ">
<tns:stock>
<tns:name>apple</tns:name>
<tns:number>1</tns:number>
<tns:description>fruit</tns:description>
</tns:stock>
<tns:stock>
<tns:name>banana</tns:name>
<tns:number>2</tns:number>
<tns:description>fruit</tns:description>
</tns:stock>
<tns:stock>
<tns:name>cap</tns:name>
<tns:number>3</tns:number>
<tns:description>accessory</tns:description>
</tns:stock>
<tns:stock>
<tns:name>door</tns:name>
<tns:number>4</tns:number>
<tns:description>furniture</tns:description>
</tns:stock>
<tns:stock>
<tns:name>elephant</tns:name>
<tns:number>5</tns:number>
<tns:description>animal</tns:description>
</tns:stock>
</tns:Input>
you get the following output:<?xml version="1.0" encoding="UTF-8"?><io:Output xmlns:io="http://www.example.org/schema">
<io:inventory>
<io:name>banana</io:name>
<io:number>2</io:number>
<io:description>fruit</io:description>
<io:index>1</io:index>
<io:count>1</io:count>
</io:inventory>
<io:inventory>
<io:name>cap</io:name>
<io:number>3</io:number>
<io:description>accessory</io:description>
<io:index>2</io:index>
<io:count>2</io:count>
</io:inventory>
<io:inventory>
<io:name>door</io:name>
<io:number>4</io:number>
<io:description>furniture</io:description>
<io:index>3</io:index>
<io:count>3</io:count>
</io:inventory>
</io:Output>
In this example, the For Each transform only runs for a restricted number of elements of the repeating element. The rest of the elements in the array are not considered. The For Each transform iterates over instances where the name of a stock item is a string with more than 4 characters.
In the For Each transform, the input element is stock and the output element is inventory.
The For Each transform iterates over instances where the value of stock.name is a string with more than 4 characters.
fn:string-length($stock/io:name) > 4
<?xml version="1.0" encoding="UTF-8"?>
<tns:Input xmlns:tns="http://www.example.org/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/schema foo.xsd ">
<tns:stock>
<tns:name>apple</tns:name>
<tns:number>1</tns:number>
<tns:description>fruit</tns:description>
</tns:stock>
<tns:stock>
<tns:name>banana</tns:name>
<tns:number>2</tns:number>
<tns:description>fruit</tns:description>
</tns:stock>
<tns:stock>
<tns:name>cap</tns:name>
<tns:number>3</tns:number>
<tns:description>accessory</tns:description>
</tns:stock>
<tns:stock>
<tns:name>door</tns:name>
<tns:number>4</tns:number>
<tns:description>furniture</tns:description>
</tns:stock>
<tns:stock>
<tns:name>elephant</tns:name>
<tns:number>5</tns:number>
<tns:description>animal</tns:description>
</tns:stock>
<tns:stock>
<tns:name>flower</tns:name>
<tns:number>6</tns:number>
<tns:description>decoration</tns:description>
</tns:stock>
<tns:stock>
<tns:name>gold</tns:name>
<tns:number>7</tns:number>
<tns:description>money</tns:description>
</tns:stock>
<tns:stock>
<tns:name>honey</tns:name>
<tns:number>8</tns:number>
<tns:description>food</tns:description>
</tns:stock>
<tns:stock>
<tns:name>igloo</tns:name>
<tns:number>9</tns:number>
<tns:description>cold</tns:description>
</tns:stock>
<tns:stock>
<tns:name>jeep</tns:name>
<tns:number>10</tns:number>
<tns:description>car</tns:description>
</tns:stock>
</tns:Input>
you get the following output:<?xml version="1.0" encoding="UTF-8"?><io:Output xmlns:io="http://www.example.org/schema">
<io:inventory>
<io:name>apple</io:name>
<io:number>1</io:number>
<io:description>fruit</io:description>
<io:index>0</io:index>
<io:count>1</io:count>
</io:inventory>
<io:inventory>
<io:name>banana</io:name>
<io:number>2</io:number>
<io:description>fruit</io:description>
<io:index>1</io:index>
<io:count>1</io:count>
</io:inventory>
<io:inventory>
<io:name>elephant</io:name>
<io:number>5</io:number>
<io:description>animal</io:description>
<io:index>4</io:index>
<io:count>2</io:count>
</io:inventory>
<io:inventory>
<io:name>flower</io:name>
<io:number>6</io:number>
<io:description>decoration</io:description>
<io:index>5</io:index>
<io:count>3</io:count>
</io:inventory>
<io:inventory>
<io:name>honey</io:name>
<io:number>8</io:number>
<io:description>food</io:description>
<io:index>7</io:index>
<io:count>4</io:count>
</io:inventory>
<io:inventory>
<io:name>igloo</io:name>
<io:number>9</io:number>
<io:description>cold</io:description>
<io:index>8</io:index>
<io:count>5</io:count>
</io:inventory>
</io:Output>
In this example, the For Each transform only runs for the first three elements of the repeating element. The rest of the elements in the array are not considered. For each element in the array, if the first 4 characters of the element B start with UK01, then the transformation inside the nested map is executed.
Inside the nested map, the fn:concat transform calculates the value of element e based on the input element index and the input element D.
<?xml version="1.0" encoding="UTF-8"?>
<NewElement>
<A>A1</A>
<C>Field_1</C>
<C>Field_2</C>
<C>Field_3</C>
<D>1000</D>
<E>CUSTOMER_AREA1</E>
</NewElement>
you get the following output:<NewElement1>
<c>
<d/>
<e>0_1000</e>
</c>
</NewElement1>
<?xml version="1.0" encoding="UTF-8"?>
<NewElement>
<A>A1</A>
<B>UK011234567</B>
<B>B2</B>
<B>UK019999999</B>
<B>UK01xxxxxxx</B>
<C>Field_1</C>
<C>Field_2</C>
<C>Field_3</C>
<D>1000</D>
<E>CUSTOMER_AREA1</E>
</NewElement>
you get the following output:<NewElement1>
<c>
<d>UK011234567</d>
<e>1_1000</e>
</c>
<c>
<d>UK019999999</d>
<e>3_1000</e>
</c>
</NewElement1>