counter Expressions

The counter expression provides counting capabilities on the expression sequences. It has the following general form:

<counter expr=”...” start-value=”...” modulo=”...” scope=”...” peek=”true|false” reset="true|false"/>

Or

<counter>
  <arg name=”expr”> ...</arg>
  <arg name=”start-value”> ...</arg>
  <arg name=”modulo”> ...</arg>
  <arg name=”scope”> ...</arg>
  <arg name=”peek”> ...</arg>
 </counter>

Note: The counter expression supports positional arguments for backwards compatibility, but named arguments are recommended.

The counter expression takes the following form when using positional arguments:

<counter>
 <arg> <!-- expr --> </arg>
 <arg> <!-- start-value --> </arg>
 <arg> <!-- modulo --> </arg>
 <arg> <!-- scope --> </arg>
 <arg> <!-- peek --> </arg>
</counter>

When using positional arguments, the order of the arguments cannot be changed and in order to specify any of the five values as an arg, all the values preceding it must also be specified.

A counter expression counts integral values. Upon evaluation the counter expression will return its current integral value and then update its counter by 1. The expression string (i.e., the expr attribute) names the counter.

All properties are optional (and default to the empty string for expr, zero for modulo and start-value, local for scope, false for peek, and false for reset).

The start-value specifies the initial value for the counter expression while modulo allows clock-like arithmetic when the counter value is updated. A modulo of zero implies no modulo specification. A counter is by default bound to the lifetime of a mapping rule activation. To bound the counter beyond this lifetime the scope attribute can be used. The valid values for the scope property are local, which is the default, parent which uses the scope of the parent node, and xfMap. Specifying xfMap for the scope bounds the counter to the xfMap. To access the value of a counter without updating its value the optional peek attribute, whose default value is false, should be set to true. The reset property may be used to return a counter to its start value.

The ability to specify properties of the counter as arguments allows these properties to be determined dynamically based on the document being read. If an argument evaluates to the empty string, then its value is ignored (and the default is used, or the previously established value in a counter with non-local scope). The reset property cannot be set dynamically; it can only be set via the reset attribute on the counter element.

Example

The example below illustrates several of the counter expression operations.

bin.xml

<?xml version=”1.0”?>
<bin>
	<item>I’m some sort of item inside this bin.</item>
	<item>What type of item may I be?</item>
	<item>I wouldn’t know.</item>
	<item>Why should I?</item>
	<item>Ask the bin.</item>
</bin>

counter.xmp

<?xml version="1.0"?>
<xfMap>
	<group-map>
		<mapping match="bin">
			<apply-attribute-sets>
				<attribute-set>
				<attributes>
				  <attribute>
						<name> <literal expr="item-order-in-bin"/> </name>
						<value><counter expr="my-counter-name"/> </value>
					</attribute>
					<attribute>
						<name> <literal expr="count-modulo-2"/> </name>
						<value>
						   <counter expr="mod-2-count">  <arg name="modulo"> <extract expr="@modulo"/> </arg>
						   </counter>
					  </value>
					</attribute>
					<attribute>
					<attribute>
						<name> <literal expr="some-other-counter"/> </name>
						<value>
						   <counter expr="my-counter-name">
						      <arg name="start-value"> <extract expr="@start"/> </arg>
						   </counter>
					  </value>
					</attribute>
					</attributes>
				</attribute-set>
			</apply-attribute-sets>
		</mapping>
	</group-map>

	<feature-map>
		<mapping match="item">
			<feature-type> <literal expr="item"/> </feature-type>
			<attributes>
				<attribute>
					<name> <literal expr="value"/> </name>
					<value><literal expr="."/> </value>
				</attribute>				
			</attributes>			
		</mapping>
	</feature-map>
</xfMap>

FME features constructed:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `item_LOGGED'
Attribute(encoded: utf-16): `count-modulo-2' has value `0'
Attribute(string) : `fme_feature_type' has value `item'
Attribute(string) : `fme_type' has value `fme_no_geom'
Attribute(encoded: utf-16): `item-order-in-bin' has value `0'
Attribute(encoded: utf-16): `some-other-counter' has value `5'
Attribute(encoded: utf-16): `value' has value `.'
Attribute(string) : `xml_type' has value `xml_no_geom'
Geometry Type: Unknown (0)
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `item_LOGGED'
Attribute(encoded: utf-16): `count-modulo-2' has value `1'
Attribute(string) : `fme_feature_type' has value `item'
Attribute(string) : `fme_type' has value `fme_no_geom'
Attribute(encoded: utf-16): `item-order-in-bin' has value `1'
Attribute(encoded: utf-16): `some-other-counter' has value `6'
Attribute(encoded: utf-16): `value' has value `.'
Attribute(string) : `xml_type' has value `xml_no_geom'
Geometry Type: Unknown (0)
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `item_LOGGED'
Attribute(encoded: utf-16): `count-modulo-2' has value `0'
Attribute(string) : `fme_feature_type' has value `item'
Attribute(string) : `fme_type' has value `fme_no_geom'
Attribute(encoded: utf-16): `item-order-in-bin' has value `2'
Attribute(encoded: utf-16): `some-other-counter' has value `7'
Attribute(encoded: utf-16): `value' has value `.'
Attribute(string) : `xml_type' has value `xml_no_geom'
Geometry Type: Unknown (0)
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `item_LOGGED'
Attribute(encoded: utf-16): `count-modulo-2' has value `1'
Attribute(string) : `fme_feature_type' has value `item'
Attribute(string) : `fme_type' has value `fme_no_geom'
Attribute(encoded: utf-16): `item-order-in-bin' has value `3'
Attribute(encoded: utf-16): `some-other-counter' has value `8'
Attribute(encoded: utf-16): `value' has value `.'
Attribute(string) : `xml_type' has value `xml_no_geom'
Geometry Type: Unknown (0)
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `item_LOGGED'
Attribute(encoded: utf-16): `count-modulo-2' has value `0'
Attribute(string) : `fme_feature_type' has value `item'
Attribute(string) : `fme_type' has value `fme_no_geom'
Attribute(encoded: utf-16): `item-order-in-bin' has value `4'
Attribute(encoded: utf-16): `some-other-counter' has value `9'
Attribute(encoded: utf-16): `value' has value `.'
Attribute(string) : `xml_type' has value `xml_no_geom'
Geometry Type: Unknown (0)
===========================================================================