The iterate attribute

The iterate attribute allows our applications to repeatedly perform the same action across a nodeset.

For example, an application that has retrieved data from an RSS feed may need to convert any dates from RFC 288 format to ISO 8601 format (the latter is used by XML Schema and therefore XForms). Also, since pubDate is optional in RSS feeds, the appication may need to create a default date if none is provided. It could do this by looping through all of the returned items and then either adding or converting pubDate.

The first step is to create a handler that will execute when the RSS feed has been loaded successfully:

<xf:action ev:observer="sub-get-rss-feed" ev:event="xforms-submit-done">

Next we set up an iterator across each of the items in the loaded RSS channel:

  <xf:action iterate="instance('inst-current-feed-rs')/channel/item">

The action handler then checks that there is actually a pubDate element, and if there is, it is converted to ISO 8601 format:

    <xf:action if="*[local-name()='pubDate']">
      <xf:setvalue ref="*[local-name()='pubDate']"
        value="inline:convrfc288datetoiso8601(.)" />
    </xf:action>

Note that the evaluation context within this action handler will be each of the nodes of the nodeset, in turn. However, since @if itself does not change the evaluation context, the setvalue action is actually being evaluated in the context of the action with the iterate attribute, and not the action with the if attribute.

There is no way to add an 'else' branch, so if we want to perform some action if there is no pubDate element, we have to repeat our previous test and use not(). If no pubDate element is present then the following code simply creates a new pubDate element and then sets it to a default value of the current date and time:

    <xf:action if="not(*[local-name()='pubDate'])">
      <xf:duplicate origin="instance('inst-control')/templates/pubDate"
        ref="." />
      <xf:setvalue ref="*[local-name()='pubDate']" value="now()" />
    </xf:action>
  </xf:action>
</xf:action>

For more information and further examples see Section 3.5 of XForms 1.1.