Loop time-limited store

Loop time-limited store

The advanced, other workflow component, Loop time-limited store is linked with the Time-limited persistent storage in workflows. Such a time-limited storage can be used for storing temporary data, which can be used to rerun input files after an issue has been solved.

The workflow component, Loop time-limited store can be compared with the repeat element of the designer in the way that it loop through all stored items in the specified storage. In each iteration, one item from the store will be copied to the payload. The predefined workflow variable, interformng.persistentStore.key will contain the key of the current item.

Related workflow components are:
  1. Delete from time-limited store Deletes an item from the time-limited store.
  2. Payload to time-limited store Saves the current payload as an item in a time-limited store.
  3. Time-limited store to payload Retrieves an item from a time-limited store.
The component has these parameters:
  1. Time-limited store
    This need to refer to the store of which you want to loop through all stored items. This is normally selected via a drop down list, but you can setup an XPath expression to select this if needed.
  2. Output type
    The output type i.e. the expected type of the item, that is retrieved.
  3. Sort keys
    Each stored item is identified by a unique key value. Here you can decide in which order the stored items should be processed. The possible values are:
  4. Unsorted
    This is default. The items will be processed in an unspecified order.
  5. Ascending
    With this value the items will be processed in ascending order according to the key value of the items.
  6. Descending
    With this value the items will be processed in descending order according to the key value of the items.
In practice, the component will first take a snapshot of the keys that exist in the store, then start the iteration. If items are added to the store while the loop is running, then those items will not be included in the iteration. If items are deleted from the store while this loop is running, then the deleted items will be skipped silently.
However, if the last item in the iteration is deleted during the loop, then one empty payload may be returned in the end. In this case the workflow variable “interformng.persistentStore.key” will be a blank string.

Below are two examples of how this component can be used:
Example 1: Load all items from a time-limited store, merge each of them into a PDF file and delete the item from the store
In this example all items in a time-limited store are loaded and each of them are merged with a template into a PDF file and the item of the store is finally deleted.
The workflow looks like this:

Here the initial input is a file found in a folder, but this is irrelevant for this example.

Each of the other components are described in details below.
Loop time-limited store
The first component in the workflow is the loop time-limited store with the settings below:

It executes the workflow to the right of this component for each item found in the store: MyTempStorage.  The items are retrieved in ascending order according to the key used for saving the item in the store.

Each time the payload is updated with the retrieved item and the workflow variable, interformng.persistentStore.key is updated with the key of this item. If nothing has been retrieved, then the variable, interformng.persistentStore.key will be empty.

Choice element
The choice element is used as a condition to ensure, that we only create a PDF file (and delete the item from the time-persistent store) if something was retrieved from the store. That is done with the condition below:

Here we use the string() function to convert the contents of the variable to a string. This is done to ensure, that the comparison with an empty string is true if the variable, interformng.persistentStore.key contains either an empty string or null.

The When branch shows as Found with this setting:


Create PDF file
Now we know we have retrieved an item, so we can now create a PDF file (based on the demo invoice xml file) like below:

The || function concatenates the text to the left of the function with the text which is found to the right.

We could have used the workflow variable, interformng.persistentStore.key if needed to identify the retrieved item, but here we simply use the contents of the payload to name the PDF file we create.

Delete from time-limited persistent store
Now it is time to delete the item from the store, that we have just processed. That is done with the component, Delete from time-persistent store as below:

Here we reuse the key, interformng.persistentStore.key to refer to the item.

Example 2: Merge all files in the time-limited store into one
In this example we want to read all files from a time-limited store and merge them all into one.

That can be done with a workflow like this:

The image above does not include the initial input part of the workflow as that is irrelevant for this demo. This could e.g. be triggered by the date or time or by an incoming file.

Each of the elements are described in the sections below.
Choice and join
We want to loop through all of the files found in the time-limited store and then process the final, merged file. That can be done with the choice and join workflow component with a dummy condition, that is always true:


In the conditioned thread we collect and merge and in the join thread we process the merged file.


Loop time-limited store
Next it is time to loop through all of the files in the time-limited store with the workflow component, Loop time-limited store:


We refer to the store and select XML as the output type as we are retrieving XML files here.
Payload to workflow variable
Now we save the payload (which is one of the retrieved files from the time-limited store) into the variable, insertXML for future reference. This is done with the component, Payload to workflow variable.




From variable to payload
Now it is time to load the variable into which we accumulate all of the files from the time-limited store. That is done with the workflow component, From variable to payload as below. Here we load the contents of the variable, mergedXML into the payload. The first time this variable is empty.



XSL transformation
Now it is time to add the new XML file, which is currently stored in the variable, insertXML into the XML file stored in the payload (and in the variable, mergedXML). That is done with the XSL transformation as below:


The transformation file contains these lines:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<!-- insertXML holds the current loop item's raw payload -->
<xsl:param name="insertXML" />
<!--
Match the root of the accumulated result so far (a Root with
0..N Document nodes, built up by previous loop iterations)
-->
<xsl:template match="/*">
<xsl:variable name="current" select="if (normalize-space($insertXML) != '') then parse-xml($insertXML)/* else ()" />
<Root>
<!-- carry forward every Document already accumulated -->
<xsl:copy-of select="Document" />
<!-- append the current payload as the newest Document node -->
<Document>
<xsl:copy-of select="$current/@*" />
<xsl:copy-of select="$current/node()" />
</Document>
</Root>
</xsl:template>
</xsl:stylesheet>

The result of the insert is an output file with this structure:

<Root>
<file1>...</file1>
<file2>...</file2>
...
</Root>
Where e.g. <file1>...</file1> is the contents of file 1.

Payload to workflow variable
This is the last workflow component inside the loop of the time-limited store. Here we update the variable, mergedXML with the current payload, which was generated by the XSL transformation in the previous step:


Save in resources
The final element is inserted in the Join thread of the Choice and join component. This is just an example where the resulting file is stored, but this could also be used as input for outputs like e.g. print, pdf or email. In this example we use the component, Save in resources to save the payload as a document: