XQuery Functions
Feature Data Functions
FME provides functions that can be used within XQuery scripts. These functions allow XQuery scripts and templates to access and manipulate feature attribute values.
All feature functions are prefixed with the fme namespace prefix.
This function is very similar to the fme:append-attribute function, but it appends to the value of a feature attribute, rather than replacing the attribute value. It has two declarations:
fme:append-attribute( <attribute name>, <sequence of values> )
fme:append-attribute( <attribute name>, <sequence of values>, <delimiter> )
The serialized value of the sequence of values will be appended to the feature attribute. If the sequence contains more than one value, the values will be concatenated into a delimited string before being appended to the attribute. The default delimiter is a comma, but the third parameter may be used to provide a different delimiter.
This function does not return a value.
This function is very similar to the fme:set-list-attribute function, but it appends to the list attribute, rather than overwriting existing values. It has only one declaration:
fme:append-list-attribute( <attribute name>, <sequence of values> )
The function serializes each value in the sequence into an element in the list attribute. Existing list values will be preserved, with the new values appended to the end of the list.
This function does not return a value.
This function retrieves the value of an attribute from the current feature. It has two declarations:
fme:get-attribute( <attribute name> )
fme:get-attribute( <attribute name>, <default value> )
If a second parameter is provided, and the feature does not have a value for the given attribute name, the function will simply return the value of the second parameter. The second parameter may be any type of XQuery value: string, number, XML node, nested function call, etc.
If a second parameter is not provided, and the feature has no value for the given attribute, the function will simply return an empty sequence.
String values returned by this function will be converted to be serializable in the context in which they are used. In particular, if the value is being inserted into an XML document, any XML syntax will be escaped. For example, < characters will become < and > will become >. The fme:get-xml-attribute function may be used to return XML nodes. Similarly, if the value is being inserted into a JSON document, the value will be enclosed in quotes, and reserved characters will be escaped. The fme:get-json-attribute may be used to return JSON objects or arrays.
Example
Consider a feature with the following attributes:
Attribute | Value |
---|---|
name |
Oranjestad |
location |
<point>-70.037 12.519</point> |
The fme:get-attribute function returns the following results:
XQuery | Result |
---|---|
<name>{fme:get-attribute( "name" )}</name> |
<name>Oranjestad</name> |
<type>{fme:get-attribute( "point_type", "city" )}</type> |
<type>city</type> |
{ "location" : fme:get-attribute( "location" ) } |
{ "location" : "<point>-70.037 12.519</point>" } |
This function allows access to a feature’s coordinate system. If a feature has a coordinate system, the function will return the name of the coordinate system. If the feature does not have a coordinate system, no value will be returned.
This function retrieves the contents of a list attribute from the current feature. It also has two declarations:
fme:get-list-attribute( <attribute name> )
fme:get-list-attribute( <attribute name>, < delimiter > )
If no delimiter parameter is provided, the function will return the list attribute as a sequence of individual items. If a delimiter parameter is provided, the function will serialize the contents of the list attribute into a single string, using the value of the delimiter parameter as a delimiter.
As with the fme:get-attribute function, all string values returned by this function will be converted to be valid XML or JSON strings, depending on the context of the function call. The fme:get-xml-list-attribute function may be used to retrieve a list of XML nodes, and the fme:get-json-list-attribute function may be used to retrieve a list of JSON objects or arrays.
Example
Consider a feature with the following attributes:
Attribute |
Value |
---|---|
dates{0} |
21-08-2010 |
dates{1} |
22-08-2010 |
dates{2} |
23-08-2010 |
The fme:get-list-attribute function returns the following results:
XQuery | Result |
---|---|
<dates> |
<dates> |
<dates> {fme:get-list-attribute( "dates", "," )} |
<dates> |
{ "dates" : fme:get-list-attribute("dates") } |
{ "dates" : [ "21-08-2010", "22-08-2010", "23-08-2010" ] } |
This function retrieves attributes containing JSON objects or arrays. It has only one declaration:
fme:get-json-attribute( <attribute name> )
If the given attribute contains JSON values, this function will parse the text and return a JSON object or array. If the attribute does not contain JSON text, the function will return an empty sequence.
Example
Consider a feature with the following attributes:
Attribute | Value |
---|---|
name |
Oranjestad |
location |
{ "type" : "point”, "x" : -70.037, "y" : 12.519 } |
The fme:get-json-attribute function returns the following results:
XQuery | Result |
---|---|
{ "location" : fme:get-json-attribute( "location" ) } |
{ "location" : { "type" : "point”, "x" : -70.037, "y" : 12.519 } } |
fme:get-json-attribute( "name" ) |
|
This function is similar to the fme:get-json-attribute function, but retrieves list attributes. It has only one declaration:
fme:get-json-list-attribute( <attribute name> )
The function attempts to parse each value in the list attribute into a JSON object or array. Values which are not valid JSON will be skipped.
Example
Consider a feature with the following attributes:
Attribute | Value |
---|---|
person{0} |
{ "name" : "John Doe", "age" : 25 } |
person{1} |
{ "name" : "Juan Domingo", "age" : 27 } |
person{2} |
{ "name" : "Johann Deuter", "age" : 29 } |
The fme:get-json-attribute function may be used as shown below:
XQuery | Result |
---|---|
{ "people" : fme:get-json-list-attribute( "person{}" ) } |
{ "people" : [ { "name" : "John Doe", "age" : 25 }, { "name" : "Juan Domingo", "age" : 27 }, { "name" : "Johann Deuter", "age" : 29 } ] } |
This function retrieves attributes containing XML nodes. It has only one declaration:
fme:get-xml-attribute( <attribute name> )
If the given attribute contains XML text, this function will parse the text and return an XML node. If the attribute does not contain XML text, the function will return an empty sequence.
Example
Consider a feature with the following attributes:
Attribute | Value |
---|---|
name |
Oranjestad |
location |
<point>-70.037 12.519</point> |
The fme:get-xml-attribute function returns the following results:
XQuery | Result |
---|---|
fme:get-xml-attribute("location" ) |
<point>-70.037 12.519</point> |
fme:get-xml-attribute("name" ) |
|
This function is similar to the fme:get-xml-attribute function, but retrieves list attributes. It has two declarations:
fme:get-xml-list-attribute( <attribute name> )
fme:get-xml-list-attribute( <attribute name>, <delimiter> )
The function attempts to parse each value in the list attribute into an XML node. Values which are not valid XML will be skipped. If the delimiter parameter is provided, it will be copied into the return sequence between each parsed XML value.
Example
Consider a feature with the following attributes:
Attribute | Value |
---|---|
person{0} |
<person> |
person{1} |
<person> |
person{2} |
<person> |
The fme:get-xml-list-attribute function may be used as shown below:
XQuery | Result |
---|---|
<people> |
<people> <person> <person> <person> </people> |
This function returns a boolean (true/false) value indicating whether or not all of the attributes listed as parameters exist on the current feature. It has one declaration:
fme:has-all-attributes( <attribute names> )
Example
Consider a feature which has a ‘name’ and an ‘id’ attribute. The fme:has-all-attributes function returns the following results:
XQuery | Result |
---|---|
fme:has-all-attributes( "name" ) |
true |
fme:has-all-attributes( "name", "id" ) |
true |
fme:has-all-attributes( "otherattr" ) |
false |
fme:has-all-attributes( "name", "other", "id" ) |
false |
This function returns a boolean (true/false) value indicating whether or not any of the attributes listed as parameters exist on the current feature. It has one declaration:
fme:has-any-attributes( <attribute names> )
Example
Consider a feature which has a ‘name’ and an ‘id’ attribute. The fme:has-any-attributes function returns the following results:
XQuery | Result |
---|---|
fme:has-any-attributes( "name" ) |
true |
fme:has-any-attributes( "name", "id" ) |
true |
fme:has-any-attributes( "otherattr" ) |
false |
fme:has-any-attributes( "name", "other", "id" ) |
true |
This function is very simple. It returns a boolean (true/false) value indicating whether or not an attribute exists on the current feature. It has one declaration:
fme:has-attribute( <attribute name> )
Example
Consider a feature which has only one attribute: ‘name’. The fme:has-attribute function returns the following results:
XQuery | Result |
---|---|
fme:has-attribute( "name" ) |
true |
fme:has-attribute( "id" ) |
false |
This function retrieves the value from a published parameter. It has only one declaration:
fme:parameter-value( <parameter name> )
Example
Consider a list of published parameters with the following values:
Parameter | Value |
---|---|
id | 1 |
name | Toronto |
The fme:parameter-value function returns the following results:
XQuery | Result |
---|---|
fme:parameter-value("id" ) | 1 |
fme:parameter-value("name" ) | Toronto |
This function sets the value of a feature attribute. It has two declarations:
fme:set-attribute( <attribute name>, <sequence of values> )
fme:set-attribute( <attribute name>, <sequence of values>, <delimiter> )
The feature attribute will be set to the serialized value of the sequence of values. If the sequence contains more than one value, the values will be concatenated into a delimited string, and the attribute will be set to this concatenated value. The default delimiter is a comma, but the third parameter may be used to provide a different delimiter.
This function does not return a value.
Example
The following XML document is the context item for the examples in this section.
<country>
<name>MONTSERRAT</name>
<area>583.776</area>
<cities>
<city>Plymouth</city>
<city>Brades</city>
</cities>
</country>
After running the following query:
fme:set-attribute( "name_xml", /country/name ),
fme:set-attribute( "area", /country/area/text() ),
fme:set-attribute( "city_list", /country/cities/city/text() ),
fme:set-attribute( "city_list2", /country/cities/city/text(), "|" )
The feature has the following attributes:
Attribute | Value |
---|---|
name_xml |
<name>MONTSERRAT</name> |
area |
583.776 |
city_list |
Plymouth.Brades |
city_list2 |
Plymouth|Brades |
This function sets the value of a feature list attribute. It has only one declaration:
fme:set-list-attribute( <attribute name>, <sequence of values> )
The function serializes each value in the sequence into an element in the list attribute.
This function does not return a value.
Example
The following XML document is the context item for the examples in this section.
<countries>
<country>
<name>Montserrat</name>
<capital>Plymouth</capital>
</country>
<country>
<name>Christmas Island</name>
<capital>The Settlement</capital>
</country>
<country>
<name>Aruba</name>
<capital>Oranjestad</capital>
</country>
</countries>
After running the following query:
fme:set-list-attribute( "names", /countries/country/name/text() ),
fme:set-list-attribute( "capitals", /countries/country/capital )
The feature has the following attributes:
Attribute | Value |
---|---|
names{0} |
Montserrat |
names{1} |
Christmas Island |
names{2} |
Aruba |
capitals{0} |
<capital>Plymouth</capital> |
capitals{1} |
<capital>The Settlement</capital> |
capitals{2} |
<capital>Orangestad</capital> |
Feature Processing Functions
Using the XMLTemplater and JSONTemplater, the template can include the results of processing a sub-template. There are two functions that allow sub-templates to be processed.
This function will evaluate a template, or set of templates, on features which enter the transformer through the corresponding input ports. The function will return the value of the sub-templates that get processed. This function has two declarations:
fme:process-features( <template names> )
fme:process-features( <template names>, <attributes to filter>, <filter values> )
In both cases, the first parameter is a template name, or list of template names. If no additional parameters are given, the function will execute the listed templates on all features which entered the transformer through the input ports which correspond to those templates. The features will be processed in the order they arrived at the transformer.
The second and third parameters can be used to filter the features which are to be processed. The second parameter should contain an attribute name, or a list of attribute names. The third parameter should contain an attribute value, or a list of values. These parameters should always have the same number of items listed. When the function is called, it will only execute the listed sub-templates on those features which match the following criteria:
- The feature entered the transformer through one of the input ports corresponding to one of the templates listed in the first parameter.
- For each of the attributes listed in the second parameter, the feature’s attribute value matches the corresponding value in the third parameter.
Example
The following function call will execute the HOUSE sub-template on all features that entered the transformer through the HOUSE input port.
fme:process-features( "HOUSE" )
The following function call will execute the HOUSE sub-template on all features that entered the transformer through the HOUSE input port, and the BUSINESS sub-template on all features which entered through the BUSINESS input port. These features will be processed in the order they arrived at the transformer.
fme:process-features( ("HOUSE", "BUSINESS" ) )
The following function call will execute the HOUSE sub-template on all features that entered the transformer though the HOUSE input port, and whose num_floors attribute is equal to 3.
fme:process-features( "HOUSE", "num_floors", 3 )
The following function call will execute the HOUSE sub-template on all features that entered the transformer through the HOUSE input port, and whose village_id attribute is equal to the id attribute of the feature currently being processed.
fme:process-features( "HOUSE", "village_id", fme:get-attribute( "id" ) )
The following function call will execute the HOUSE sub-template on all features that entered the transformer through the HOUSE input port, and whose num_floors attribute is equal to 3, and whose village_id attribute is equal to the id attribute of the feature currently being processed.
fme:process-features( "HOUSE", ( "num_floors", "village_id" ), ( 3, fme:get-attribute("id") ) )
This function will evaluate a template, or set of templates. Unlike the fme:process-features function, it will evaluate the template on the same feature as the template that contains the function call is being evaluated on. The function has only one declaration:
fme:process-template( <template names> )
The only parameter to this function is a template name, or a list of template names. If more than one name is provided, the templates will be evaluated in the order they are listed.
Example
The following function call will execute the OWNER template.
fme:process-template( "OWNER" )
The following function call will execute the OWNER and ADDRESS templates.
fme:process-template( ( "OWNER", "ADDRESS" ) )
Geometry Data Functions
FME provides a number of functions for accessing geometry data using XQuery. All geometry data functions are prefixed with the “geom” namespace prefix.
This function returns information about arc geometries. If the current geometry is not an arc, the function will not return a value. The function has the following declaration:
geom:get-arc-data( <data names> )
The function expects to be passed a list of strings naming the data which it is to return. The function will return the values as a sequence, in the order they are listed in the function call. Valid names are:
bulge | primary-radius | secondary-radius |
start-angle | sweep-angle | rotation |
center-x | center-y | center-z |
start-x | start-y | start-z |
mid-x | mid-y | mid-z |
end-x | end-y | end-z |
Example
geom:get-arc-data( "sweep-angle" )
geom:get-arc-data( "center-x", "center-y", "center-z" )
This function returns the dimension of the geometry currently being processed, as an integer value.
This function returns data about ellipse geometries. If the current geometry is not an ellipse, the function will not return a value. The function has the following declaration:
geom:get-ellipse-data( <data names> )
The function expects to be passed a list of strings naming the data which it is to return. The function will return the values as a sequence, in the order they are listed in the function call. Valid names are:
center-x | center-y | center-z |
rotation | primary-radius | secondary-radius |
Example
geom:get-ellipse-data( "primary-radius", "secondary-radius" )
geom:get-ellipse-data( "rotation" )
These functions return x/y/z values of the end point of linear geometries, such as lines, arcs and paths. If the geometry is a point, these functions will return the x/y/z values of the point geometry. These functions will not return a value for any other type of geometry.
This function returns the name of the geometry currently being processed. If the geometry does not have a name, this function will not return a value.
This function returns a string containing the point values of all points in the geometry being processed. For curved geometries, such as ellipses and arcs, the points in the stroked version will be used. This function has three declarations:
geom:get-points()
geom:get-points( <axis-order> )
geom:get-points( <axis-order>, <axis-separator>, <point-separator> )
The axis order parameter is a string, indicating which order the x, y and z coordinates should appear in the string. If the parameter is not given, the order “xyz” is used. The second parameter indicates the delimiter which is to be used between the x, y, and z values in a point, while the third parameter indicates the delimiter which is to be used between each point. The default axis delimiter is a comma, and the default point delimiter is a space.
Example
geom:get-points( "xy" )
geom:get-points( "yxz" )
geom:get-points( "yx", "/", " " )
geom:get-points( "xyz", " ", "," )
The last example reverses the default axis and point separators, using a space between the axes and a comma between each point.
These functions return x/y/z values of the start point of linear geometries, such as lines, arcs and paths. If the geometry is a point, these functions will return the x/y/z values of the point geometry. These functions will not return a value for any other type of geometry.
This function returns information about text geometries. If the current geometry is not a text geometry, the function will not return a value. The function has the following declaration:
geom:get-text-data( <data names> )
The function expects to be passed a list of strings naming the data which it is to return. The function will return the values as a sequence, in the order they are listed in the function call. Valid names are:
Example
geom:get-text-data( "rotation" )
geom:get-text-data( "size", "string" )
This function is almost identical to the fme:get-attribute function. It returns the value of a trait on the geometry currently being processed. It has two declarations:
geom:get-trait( <trait name> )
geom:get-trait( <trait name>, <default value> )
If a second parameter is provided, and the geometry does not have a value for the given trait, the function will simply return the value of the second parameter. The second parameter may be any type of XQuery value: string, number, XML node, nested function call, etc.
If a second parameter is not provided, and the geometry has no value for the given trait, the function will not return a value.
These functions return the x/y/z values of a point geometry. They will not return a value if they are executed on a non-point geometry.
Examples:
{
"x" : geom:get-x-coord(),
"y" : geom:get-y-coord(),
"z" : geom:get-z-coord()
}
<point x="geom:get-x-coord()" y="geom:get-y-coord()" z="geom:get-z-coord()" />
Geometry Processing Functions
When evaluating a template, XQuery functions now have access to geometry. By default, the geometry which is accessed is simply the geometry associated with the feature which is being processed. However, using the functions described in this section, the geometry which is being processed may be changed. For example, if a feature’s geometry is an aggregate, the geom:process-parts function may be used to sequentially evaluate a sub-template on each part of the aggregate. While these sub-templates are being evaluated, the geometry data functions listed above will access the individual parts of the aggregate, rather than the aggregate as a whole.
Note that it is possible for a template to be called recursively, if a different geometry is being accessed in each evaluation of the template. This allows the processing of nested aggregate geometries to arbitrary depths, simply by using the geom:process-parts function.
Each of these functions, except the geom:process-points function, takes a parameter which defines which template to run for different geometry types. This mapping is done using an XML element, named ‘conf’ which contains attributes for the different geometry types. The attribute values contain the name of the template which is to be run for that geometry type. If a geometry does not have a type attribute in the conf element, or if the attribute contains an empty string, no template will be evaluated.
Example
If the following conf element is passed to a function, the function will evaluate the ROAD template on all line geometries, the POI template on all point geometries, and the PARCEL template on all polygon geometries.
<conf line="ROAD" point="POI" polygon="PARCEL" />
The following values are valid geometry type names for the conf element:
aggregate | box | brepsolid |
composite-solid | composite-surface | csgsolid |
donut | ellipse | extrusion |
face | line | mesh |
multi-area | multi-curve | multi-point |
multi-solid | multi-surface | multi-text |
null | path | point |
pointcloud | polygon | raster |
rectangle-face | text | triangle-fan |
triangle-strip |
In addition to the above type names, there are a number of attributes that may be used in the conf element to name a template to run for a group of related geometry types.
Conf Attribute Name | Effect |
---|---|
all | The named template will be evaluated for geometries of any type. |
area | The named template will be evaluated for polygon, donut and ellipse geometries. |
collection | The named template will be evaluated for aggregates and multi-geometries, such as multi-points, multi-curves, etc. |
curve | The named template will be evaluated for line, arc and path geometries. |
If more than one conf attribute name is applicable to a geometry, the value of the more specific attribute name will be used. Thus, the value of the all will only be used if no other attributes are applicable.
Example
If the following conf element is passed to a function, the function will evaluate the PATH template on all line and arc geometries, the PATH template on path geometries, and the OTHER template on all other geometries.
<conf curve="SEGMENT" path="PATH" all="OTHER" />
While these conf elements name a template to run geometries of a particular type, a geometry trait may be used to name a template which is to be run for a particular geometry instance. Setting the geometry_template trait on a particular geometry to a template name will make the functions run that template for that geometry, rather than the template named in the conf element.
This function will evaluate a sub-template, based on the type of the geometry currently being processed. This allows a different sub-template to be run for each geometry type. This function has the following declaration:
geom:process-geometry( <conf/> )
As described above, the conf element parameter, or the geometry_template trait will indicate which template to run for each geometry type.
Example
geom:process-geometry( <conf line="ROAD" point="POI" polygon="PARCEL" /> )
If the geometry currently being processed is a collection (an aggregate or multi-geometry), this function will evaluate a sub-template for each part of the collection. The individual geometries will be processed in the order they appear in the collection, and a sub-template will be chosen based on the type of the geometry. This function may be used to evaluate a template recursively, for example if an aggregate geometry contains another aggregate geometry. As with the other functions in this section, this function takes a conf element as a parameter, which indicates which templates to run for different geometry types.
This function can also be used to evaluate sub-templates on the parts of geometries which are not typically thought of as collections. For example, if the geometry being processed is a path, this function may be used to evaluate a sub-template on each segment of the path. Similarly, if the current geometry is a donut, this function may be used to evaluate a sub-template on each inner boundary of the donut.
This function does not return anything if the geometry being processed is not a collection, path or donut geometry.
Example
geom:process-parts( <conf area="PARCEL" curve="ROAD" /> )
This function evaluates a sub-template on all points which make up the geometry currently being processed. For example, if the current geometry is a line, the function will evaluate a sub-template on each vertex in the line. If the current geometry is a polygon, the function will evaluate a sub-template on each vertex in the polygon boundary. Arcs and ellipses will be stroked, and a sub-template will be evaluated on each point in the stroked line or polygon. This function has one declaration; unlike the other functions in this section, it does not take a conf element, but takes a single string parameter instead.
geom:process-points( <sub-template name> )
Example
geom:process-points( "WAYPOINT" )
geom:process-boundary
If the geometry being processed is an area, this function can be used to evaluate a sub-template on the boundary of the area. This function only applies to polygon, donut and ellipse geometries. It has the following declaration.
geom:process-boundary( <conf line="" arc="" path="" /> )
Since the boundary of an area will always be a line, arc or path, these are the only conf attributes which are used by the function, along with the more generic ‘curve’ and ‘all’ attributes. The geom:process-parts function may be used to evaluate a sub-template for each inner boundary of a donut.
Published Parameters
The XQueryFactory can retrieve the values of any published parameters (or macros) in a workspace (or mapping file). These values are global variables in a query, and may be accessed using the ‘fme’ prefix and the parameter/macro name. For example, to access the FME_HOME macro value, the $fme:FME_HOME variable may be used. Due to a restriction of the XQuery language, parameters/macros whose names begin with a number are not accessible in this way.