Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »


Description

The for each statement enumerates the elements of a collection, executing an embedded statement for each element of the collection.

Syntax

For Statement Syntax
<For each=”<variable[s]>” in=”<source data key>” from=”<source data key prefix>” using="<variable store key>">
                …facet script …
</For>

Syntax Notes

Examples of each of these variations will be provided in the next section.

Tag

Optional/Required

Description
ForRequiredLoop is implemented as a generic FacetScript construct  and NOT specific to any facet so you can use it anywhere FacetScript can be used.
Each=Required

"each" defines loop variable[s] name[s]

  • One variable form: each=”var_name” this is used to iterate over values

  • Two variables form: each=”key_var:value_var” this is used to iterate over entries (i.e. key:value pairs)
  • Two variables form can be used to define only one (e.g. “key_var:” or “:value_var”)

  • Variable names can be “deep” i.e. contain dots in them (e.g. “obj.type:obj.value”)

in=Required

“in” specifies the source key to iterate over

from=Optional

“from” specifies the source key prefix. Default value is “$Response.Message.Value”. That is, loop will [virtually] concatenate from+in to obtain actual key and some optimizations.

using=Optional

“using” specifies the data store where loop variable[s] will be allocated. Default value is “$LocalData”. That is, since loop body is a scope, a new loop variable[s] will be created for each loop iteration. If you need to pass/keep some data between iteration then you can use a different store (e.g. $ProcessData, $ContextData etc.), combination of stores or wrap loop in another scope and initialize your data there

Tips and Caveats

  • If you use $LocalData your loop variables will NOT be available after the loop (they are defined in the scope of iteration only)
  • We are manipulating structures, so the general idea is to assign a STRUCTURE to a loop variable so you can manipulate the CONTENT of the structure through the variable. That is, <For each=”val” in=”Find.Result.VendorInfo.VendorTitle.Value”> will allow you to do if/select on the val, but will NOT allow you to change the VendorTitle, only the value of loop variable which is a simple value in this case.

    Caveat Example

    Assign STRUCTURE
    <Query>
      <Find format="Version">
        <VendorInfo>
          <vendorTitle eq="Sensor Provider"/>
        </VendorInfo>
      </Find>
      <For each="val" in="Find.Result.VendorInfo.VendorTitle.Value">
        <IF Condition="/'[:$LocalData.val:]' eq 'Sensor Provider'"> <!-- This is simply to show how if can be used -->
           <Log Message="Found Sensor Provider"/>
        </IF>
        <SetLocalData Key="val" Value="Actuator Provider"/> <!-- This will change <Value> only -->
      </For>
      <!-- Do an Update -->
      <Update>
        <From>Result</From>
        <Include>$Response.Message.Value.Find</Include>
      </Update>
    </Query>
     
    <!-- Result is.. -->
    <Find Status="Success" Format="version">
      <Result>
        <VendorInfo>
          <VendorSysId>KQN7B5X7AAAAUAABBN7HUYCE</VendorSysId>
          <vendorTitle Value="Sensor Provider" Version="1"/>
          <vendorName Value="Libelium" Version="2"/>
        </VendorInfo>
      </Result>
      <Result>
        <VendorInfo>
          <VendorSysId>KQN7BUUZAAAAUAABBPXOPXWG</VendorSysId>
          <vendorTitle Value="Sensor Provider" Version="1"/>
          <vendorName Value="Phidget" Version="1"/>
        </VendorInfo>
      </Result>
      <Result>
        <VendorInfo>
          <VendorSysId>KQN7CBXVAAAAUAABBNFHWPBK</VendorSysId>
          <vendorTitle Value="Sensor Provider" Version="1"/>
          <vendorName Value="Phidget3" Version="1"/>
        </VendorInfo>
      </Result>
    </Find>
    <Update Status="Success" Format="version">
      <VendorInfo>
        <VendorSysId>KQN7B5X7AAAAUAABBN7HUYCE</VendorSysId>
        <vendorName Status="Success_NoAction:2:1460829683086;" Value="Libelium" Version="2"/>
        <vendorTitle Status="Success_NoAction:1:1460757657344;" Value="Sensor Provider" Version="1"/> <!-- Note there is no change in value -->
      </VendorInfo>
      <VendorInfo>
        <VendorSysId>KQN7BUUZAAAAUAABBPXOPXWG</VendorSysId>
        <vendorName Status="Success_NoAction:1:1460757648025;" Value="Phidget" Version="1"/>
        <vendorTitle Status="Success_NoAction:1:1460757648027;" Value="Sensor Provider" Version="1"/> <!-- Note there is no change in value -->
      </VendorInfo>
      <VendorInfo>
        <VendorSysId>KQN7CBXVAAAAUAABBNFHWPBK</VendorSysId>
        <vendorName Status="Success_NoAction:1:1460757661429;" Value="Phidget3" Version="1"/>
        <vendorTitle Status="Success_NoAction:1:1460757661429;" Value="Sensor Provider" Version="1"/> <!-- Note there is no change in value -->
      </VendorInfo>
    </Update>

    Correct way is to point val → Find.Result.VendorInfo 

    Assign to STRUCTURE
    <Query>
      <Find format="Version">
        <VendorInfo>
          <vendorTitle eq="Sensor Provider"/>
        </VendorInfo>
      </Find>
      <For each="val" in="Find.Result.VendorInfo">
        <IF Condition="/'[:$LocalData.val.vendorTitle.Value:]' eq 'Sensor Provider'">
          <Log Message="Found Sensor Provider"/>
        </IF>
        <SetLocalData Key="val.vendorTitle.Value" Value="Actuator Provider"/>
      </For>
      <!-- Do an Update -->
      <Update>
        <From>
          Result
        </From>
        <Include>
          $Response.Message.Value.Find
        </Include>
      </Update>
    </Query>
    <!-- Result is -->
    <Find Status="Success" Format="version">
      <Result>
        <VendorInfo>
          <VendorSysId>KQN7B5X7AAAAUAABBN7HUYCE</VendorSysId>
          <vendorTitle Version="3" Value="Actuator Provider"/>
          <vendorName Value="Libelium" Version="2"/>
        </VendorInfo>
      </Result>
      <Result>
        <VendorInfo>
          <VendorSysId>KQN7BUUZAAAAUAABBPXOPXWG</VendorSysId>
          <vendorTitle Version="3" Value="Actuator Provider"/>
          <vendorName Value="Phidget" Version="1"/>
        </VendorInfo>
      </Result>
      <Result>
        <VendorInfo>
          <VendorSysId>KQN7CBXVAAAAUAABBNFHWPBK</VendorSysId>
          <vendorTitle Version="3" Value="Actuator Provider"/>
          <vendorName Value="Phidget3" Version="1"/>
        </VendorInfo>
      </Result>
    </Find>
    <Update Status="Success" Format="version">
      <VendorInfo>
        <VendorSysId>KQN7B5X7AAAAUAABBN7HUYCE</VendorSysId>
        <vendorName Status="Success_NoAction:2:1460829683086;" Value="Libelium" Version="2"/>
        <vendorTitle Status="Success=Updated:4:1460935288963;" Value="Actuator Provider" Version="4"/> <!-- Title is updated -->
      </VendorInfo>
      <VendorInfo>
        <VendorSysId>KQN7BUUZAAAAUAABBPXOPXWG</VendorSysId>
        <vendorName Status="Success_NoAction:1:1460757648025;" Value="Phidget" Version="1"/>
        <vendorTitle Status="Success=Updated:4:1460935288964;" Value="Actuator Provider" Version="4"/> <!-- Title is updated -->
      </VendorInfo>
      <VendorInfo>
        <VendorSysId>KQN7CBXVAAAAUAABBNFHWPBK</VendorSysId>
        <vendorName Status="Success_NoAction:1:1460757661429;" Value="Phidget3" Version="1"/>
        <vendorTitle Status="Success=Updated:4:1460935288964;" Value="Actuator Provider" Version="4"/> <!-- Title is updated -->
      </VendorInfo>
    </Update>

Examples

Iterating over Query Result
<Query>
  <Find format="Version">
    <VendorInfo>
      <vendorSysId ne=""/>
    </VendorInfo>
  </Find>
<For each="val" in="Find.Result.VendorInfo"> <!-- Note that since From is not specified: It will default to $Response.Message.Value -->
    <Log Message="Vendor Name is: [:$LocalData.val.vendorName.Value:]"/>
</For>
</Query>
Using a non-default store
<SetContextData Key="Atomiton.FS.Features.1" Value="Conditional Statements"/>
<SetContextData Key="Atomiton.FS.Features.2" Value="For Statements"/>
<SetContextData Key="Atomiton.FS.Features.3" Value="Case Statements"/>
<!-- Let's iterate over ContextData -->
<For each="val" In="Atomiton.FS.Features" From="$ContextData">
    <Log Message="...[:$LocalData.val:]"/>
</For>
Specify the local store
<SetContextData Key="Atomiton.FS.Features.1" Value="Conditional Statements"/>
<SetContextData Key="Atomiton.FS.Features.2" Value="For Statements"/>
<SetContextData Key="Atomiton.FS.Features.3" Value="Case Statements"/>
<!-- Let's iterate over ContextData and use ProcessData to store iterated data -->
<For each="val" in="Atomiton.FS.Features" from="$ContextData" using="$ProcessData">
  <Log Message="within loop...[:$ProcessData.val:]"/>
</For>
Looping from ContextData
<For each="light" in="Message.Value.lights" from="$ContextData.response">
  <SetContextData key="state">
          <value>
              <intensityLevel>-1</intensityLevel>
              <powerConsumption>-1</powerConsumption>
              <reliability>0</reliability>
            </value>
          </SetContextData>
          <if condition="[:$LocalData.light.location/count(latitude) gt 0:]">
            <then>
             ...
			</then>
		</if>
</For>       
  • No labels