MashZone NextGen 10.2 | Appendix | Legacy Presto components | Mashables and Mashups | Mashups in EMML | Writing Mashups in EMML | Controlling Mashup Processing Flow | <foreach> | <foreach> Examples
 
<foreach> Examples
<foreach> as Sequential Loops
For sequential loops, you must set two attributes: items and variable. You define the set of nodes to iterate through in the items attribute with an XPath expression. You can use predicates to control which nodes are selected, or use XPath functions as needed.
You must also identify a variable to hold each iteration of the set of nodes. XPath expressions for statements within <foreach> use this iteration variable to access data for the current node.
Note: The iteration variable is declared implicitly and has a local scope within <foreach> only.
The following example iterates through employee nodes. Within the loop, it uses an <if> statement to test the current employee node before adding content to a variable using <appendresult>.
<foreach variable="staff" items="$employees_Array//employee">
<if condition="$staff/department = 'Accounting' and
$staff/years > 5">
<appendresult outputvariable="$employeesResult">
<res:vested>
<res:name>{$staff/name)}</res:name>
<res:vestedYears>{$staff/years - 5}</res:vestedYears>
</res:vested>
</if>
</appendresult>
</foreach>
<foreach> as Parallel Loops for All Nodes
With concurrent loop processing, you define the iterations and variables just as you do for sequential loop processing. You set parallel="yes" and use the remaining attributes, plus a <fuse> child, to define how the concurrent loops are processed and how loop results are merged.
When concurrent processing is used, each node identified in the items attribute spawns a new concurrent task. Set tasks="invokeall" to ensure that each loop completes processing.
<foreach variable="url" items="$urls/url/string()" parallel="yes"
tasks="invokeall" merge="true">
<!-- invoke several web sites in parallel -->
<directinvoke endpoint="$url" outputvariable="$tempResult"/>
<!-- merge all results and construct final result -->
<fuse outputvariable="$summary">
<feedsummary title="{$tempResult/rss/channel/title}" url="{$url}">
{$tempResult/rss/channel/item[1]/title}
</feedsummary>
</fuse>
</foreach>
With concurrent processing, you must construct the output of <foreach> with a <fuse> child. You define the literal XML for the result within the body of <fuse> and use static values or Dynamic Mashup Expressions to define how data is assigned to the result.
The outputvariable for <fuse> combined with the merge attribute on <foreach> determines what variable(s) hold the result(s) of the concurrent loops. To aggregate all the loop results in a single variable, set merge to true as shown in this example.
Note: The order in which loop results are added to the combined, final result is not determinant.
The final result, assigned to the summary variable, for the previous concurrent <foreach> example would look something like this:
<taskresults>
<taskresult>
<feedsummary title="Yahoo! Finance"
url="http://finance.yahoo.com/rss/headlines">
Facebooks Boots CFO Yu, Here Comes the IPO</feedsummary>
</taskresult>
<taskresult>
<feedsummary title="Business and Financial News - CNNMoney.com"
url="http://rss.cnn.com/rss/money_topstories.rss">
Auto bankruptcy, What it means</feedsummary>
</taskresult>
...
</taskresults>
Each loop creates a <taskresult> element in which the <fuse> structure appears.
If you set the merge attribute to false, the results of each loop is assigned to its own variable. The outputvariable value for <fuse> is used to create individual variables as output-variable-name1, output-variable-name2 and so on.
Note: The order in which loop results are assigned to individual, final result is not determinant.
The combined outputvariable contains references to each individual loop result. For the previous example, the final result assigned to the summary variable would look something like this:
<taskresults>
<taskresult>$summary1</taskresult>
<taskresult>$summary2</taskresult>
...
</taskresults>
<foreach> as Parallel Loops for Any One Node
With concurrent loops, you can also stop all further loop processing once one loop completes using tasks set to invokeany. The first loop that completes stops all other loops.
<foreach variable="url" items="$urls/url/string()" parallel="yes"
tasks="invokeany" merge="true">
<!-- invoke several web sites in parallel, stop when one returns -->
<directinvoke endpoint="$url" outputvariable="$tempResult"/>
<!-- construct final result -->
<fuse outputvariable="$summary">
<feedsummary title="{$tempResult/rss/channel/title}" url="{$url}">
{$tempResult/rss/channel/item[1]/title}
</feedsummary>
</fuse>
</foreach>
You must still define the structure of the result using a <fuse> child and specifying the variable to hold the result. With this example, the summary variable might look something like this:
<taskresults>
<taskresult>
<feedsummary title="Business and Financial News - CNNMoney.com"
url="http://rss.cnn.com/rss/money_topstories.rss">
Auto bankruptcy, What it means</feedsummary>
</taskresult>
</taskresults>
Working Samples
The following sample mashups use the <foreach> statement:
*ConcurrentInvokes (concurrent1.emml) and (concurrent2.emml)
*DynamicInvoke (dynamicinvoke.emml)
*GoogleFinanceNews (googlefinancenews.emml)
*GroupByService (groupby2.emml)
*LevenshteinDistanceJoin (levend.emml)
*GoogleWebClipping (webclipping.emml)
See Mashup Samples for a list of MashZone NextGen mashup samples and where to find them.

Copyright © 2013-2018 | Software AG, Darmstadt, Germany and/or Software AG USA, Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors.
Innovation Release