Define Element

The <define> element allows expression sequences to be named and referenced in other expression sequences through that name. It contains a sequence of one or more <let> elements. Each <let> element defines a let definition, and the name of the let definition is specified via the <let> element’s name attribute while its value is an expression sequence:

<define>
	<let name=”myExprSeq”>
		<!-- some expression sequence -->
	</let>
	<let name=”myOtherExprSeq”>
		<!-- some expression sequence -->
	</let>
	...		
</define>

These let expression sequences may be accessed in two different ways: by the defnval expressions, or by the <condition> element’s Boolean expression % token. The defnval expression is described in defnval Expressions. This section describes the % token in the <condition> element’s Boolean expressions.

Recall that unlike the mapping rule’s match Boolean expression, the Boolean expressions from the <condition> element may contain an extra % token, which is reproduced for reference below.

booleanExpr = 	attrCondition
	|	andExpr
	|	orExpr
	| ‘(‘ booleanExpr ‘)’

andExpr = booleanExpr ‘and’ booleanExpr
orExpr = booleanExpr ‘or’ booleanExpr

attrCondition = ‘@’attrName(‘+’ | ‘-’) | 
‘@’attrName(‘=’|’!=’)’%’? (‘"‘|"‘")attrValue(‘"‘|"‘")

The token % means to interpret the attrValue as the name of a let definition. The value of the let definition attrValue, an expression sequence, is then substituted for comparison.

The following example illustrates how the let definitions may be accessed through the <condition> element’s Boolean expressions.

players.xml

<?xml version=”1.0”?>

<players>
	<positions>
		<position name=”Josephine” type=”forward”/>
		<position name=”Joan” type=”backward”/>
	</positions>
	<player>
		<name>Josephine</name>
		<age>16</age>
	</player>
	<player>
		<name>Joan</name>
		<age>17</age>
	</player>
</players>

We would like to map each <player> element into an FME feature. We would also like to add a position attribute that describes the player’s position to the FME feature. Notice that all position information precedes the data of the individual players; therefore we’ll use group mapping rules:

players.xmp

<?xml version=”1.0”?>

<xfMap>
	<group-map>
		<!-- We create this group so that the groups that are constructed
			out of the position elements can persist here. -->
		<mapping match=”players”/>		
	</group-map>

	<group-content-map>
		<mapping match=”positions/position”>
			<!-- A group is constructed for every position element, when 
				the position element end-tag is read the group is defined
				to persist in its parent-group (i.e., the group defined 
				in the group-map above). -->
				
			<define>
				<!-- This let definition will be access by the 
					condition element below. We want to keep track
					of the name of this player that started this group. -->
				<let name=”playerName”> <extract expr=”@name”/> </let>
			</define>
			<persist/>
			<apply-attribute-sets>
				<attribute-set>
					<!-- Only features that have an attribute called
						‘name’ with its value equal to the value
						of the expresion sequence denoted by ‘playerName’
						will receive the attribute set. -->
					<condition feature=”@name=%’playerName’”/>
					<attributes>
						<attribute>	
							<name> <literal expr=”position”/> </name>
							<value> <extract expr=”@type”/> </value>
						</attribute>
					</attributes>
				</attribute-set>
			</apply-attribute-sets>			
		</mapping>			
	</group-content-map>

	<feature-map>
		<mapping match=”player”>
			<feature-type> <literal expr=”player”/>
			<attributes>
				<attribute>
					<name> <literal expr=”name”/> </name>
					<value> <extract expr=”./name”/> </value>
				</attribute>
				<attribute>
					<name> <literal expr=”age”/> </name>
					<value> <extract expr=”./age”/> </value>
				</attribute>
			</attributes>
		</mapping>
	</feature-map>
</xfMap>

The FME features output when the above players.xml and players.xmp are fed into the XML Reader are:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `player'                                                     
Attribute: `age' has value `16'                                            
Attribute: `name' has value `Josephine'                                    
Attribute: `position' has value `forward'                                  
Attribute: `xml_type' has value `xml_no_geom'                              
Geometry Type: Unknown (0)                                                 
===================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `player'                                                     
Attribute: `age' has value `17'                                            
Attribute: `name' has value `Joan'                                         
Attribute: `position' has value `backward'                                 
Attribute: `xml_type' has value `xml_no_geom'                              
Geometry Type: Unknown (0)                                                 
===================================================================

Notice that the player FME features contain the position element with their correct attribute values.