MashZone NextGen 10.2 | Appendix | Legacy Presto components | Mashables and Mashups | Mashups in MashZone NextGen Wires | Customizing Wires | Adding Custom Blocks to MashZone NextGen Wires Using Macros | Loop Through a Well-Known Input
 
Loop Through a Well-Known Input
One very common use case for custom blocks is to take results from a mashup or mashable information source, loop through each item in the results and add or transform data in the results.
When the structure of the input is well known, common steps that a looping macro may need to complete are:
1. Define <output> with a root node that will wrap the items added by the macro during looping. See Creating a Root Node for the Macro Result.
2. Begin looping through the input. See Looping With <foreach> and a Well-Known Input Structure.
3. Generate the appropriate output for each loop. See Using <appendresult> to Transform Input and Build the Output.
Creating a Root Node for the Macro Result
You must add an <output> statement for the macro to allow the custom action in Wires to be wired to other blocks or to the output of the mashup itself. When a macro loops through the input block results, you can also create the root node for the macro output within the <output> statement itself. Simply add an empty element within <output>.
This example defines a root node, <statistics>, for the macro output:

<macros xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openmashup.org/schemas/v1.0/EMML/ ../src/schemas/EMMLSpec.xsd"
xmlns="http://www.openmashup.org/schemas/v1.0/EMML"
xmlns:presto="http://www.jackbe.com/v1.0/EMMLPrestoExtensions"
domain = "myCustomMath">

<macro name="GetSessionPercentages">
<!-- Spreadsheet with Session data is input -->
<input name="spreadsheet" type="document" />
<!-- create wrapper for results that macro will append to -->
<output name="result" type="document">
<statistics />
</output>
...
</macro>
...
</macros>>
Looping With <foreach> and a Well-Known Input Structure
You use <foreach> to loop through a set of repeating items, in this case the input mashable results.
With <foreach> you define a variable to hold each item and use an XPath expression to define the items to loop through. The input for this example comes from an spreadsheet mashable:

<SessionStatsData>
<item>
<Categories>FormA</Categories>
<Session1>23</Session1><Session2>30</Session2><Session3>35</Session3>
<Session4>11</Session4><Session5>23</Session5><Session6>15</Session6>
</item>
<item>
<Categories>FormC</Categories>
<Session1>15</Session1><Session2>10</Session2><Session3>13</Session3>
<Session4>15</Session4><Session5>5</Session5><Session6>11</Session6>
</item>
<item>
<Categories>FormD</Categories>
<Session1>37</Session1><Session2>78</Session2><Session3>51</Session3>
<Session4>66</Session4><Session5>77</Session5><Session6>25</Session6>
</item>
<item>
<Categories>FormL</Categories>
<Session1>8</Session1><Session2>3</Session2><Session3>6</Session3>
<Session4>4</Session4><Session5>5</Session5><Session6>6</Session6>
</item>
<item>
<Categories>FormR</Categories>
<Session1>19</Session1><Session2>22</Session2><Session3>7</Session3>
<Session4>15</Session4><Session5>10</Session5><Session6>13</Session6>
</item>
</SessionStatsData>
The <foreach> loop would look something like this:

<macros xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openmashup.org/schemas/v1.0/EMML/ ../src/schemas/EMMLSpec.xsd"
xmlns="http://www.openmashup.org/schemas/v1.0/EMML"
xmlns:presto="http://www.jackbe.com/v1.0/EMMLPrestoExtensions"
domain = "myCustomMath">
<macro name="GetSessionPercentages">
<input name="spreadsheet" type="document" />
<output name="result" type="document">
<statistics />
</output>
<!-- loop through items in spreadsheet -->
<foreach variable="$category" items="$spreadsheet//item">
...
</foreach>
</macro>
...
</macros>>
Within the loop, the category variable holds each item during an iteration. The XPath that defines what node to use as an item is specifically defined based on the well known structure of the input.
Using <appendresult> to Transform Input and Build the Output
Within the loop, you add to the output using <appendresult>. You define the structure of the output as literal XML and use dynamic mashup expressions to perform calculations, transform data and fill the output. See Dynamic Mashup Expressions for basic instructions.
This example adds a <category> element for each item in the loop and calculates percentages for the session statistics. The content for <appendresult> is again specifically defined from the known structure of the input.

<macros xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openmashup.org/schemas/v1.0/EMML/ ../src/schemas/EMMLSpec.xsd"
xmlns="http://www.openmashup.org/schemas/v1.0/EMML"
xmlns:presto="http://www.jackbe.com/v1.0/EMMLPrestoExtensions"
domain = "myCustomMath">

<macro name="GetSessionPercentages">
<input name="spreadsheet" type="document" />
<output name="result" type="document">
<statistics />
</output>
<!-- loop through items in spreadsheet -->
<foreach variable="$category" items="$spreadsheet//item">
<!-- add a category and calculate percentages for each item -->
<appendresult outputvariable="$result">
<category>
<name>{$category/Categories/string()}</name>
<session1PC>{$category//Session1/number() div 100}</session1PC>
<session2PC>{$category//Session2/number() div 100}</session2PC>
<session3PC>{$category//Session3/number() div 100}</session3PC>
<session4PC>{$category//Session4/number() div 100}</session4PC>
<session5PC>{$category//Session5/number() div 100}</session5PC>
<session6PC>{$category//Session6/number() div 100}</session6PC>
</category>
</appendresult>
</foreach>
</macro>
...
</macros>>

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