Syntax FACTORY_DEF * XQueryFactory [FACTORY_NAME ] [INPUT SOURCE_DOCUMENT FEATURE_TYPE [ ]* []*]+ [INPUT QUERY_DOCUMENT FEATURE_TYPE [ ]* []*]+ [MODE (SINGLE_FEATURE|DYNAMIC_XML|DYNAMIC_QUERIES)] [XML_FILE | XML_ATTR ] [XQUERY_FILE ]* [XQUERY_EXPR ]* [XQUERY_ATTR ]* [EXTRACT_MODE [(yes|no)]] [EXPLODE_MODE [(yes|no)]] [EXTRACT_TYPE (CSV|STRING|CSV_LIST|LIST)] [SIMPLIFY_ON_SINGLE [(yes|no)]] [RESULTS_SEPARATOR ] [QUERY_SEPARATOR ] [TAG_QUERY_ATTRIBUTE ] [WRITE_HEADER [(yes|no)]] [COPY_INPUT_ATTRS [(yes|no)]] [REMOVE_SOURCE_XML_ATTR [(yes|no)]] [USE_W3C_UPDATE_EXTENSIONS [(yes|no)]] [STATIC_QUERY [(yes|no)]] [REJECT_INVALID_GEOM (yes|no)] [RESULT_ATTR ] [OUTPUT (QUERY_RESULTS|INVALID_QUERY|REJECTED) FEATURE_TYPE [ ]* []*]* Overview This factory uses XQuery Expressions/Documents to extract values from XML documents stored in a file (XML_FILE) or as an attribute on a feature (XML_ATTR). Since XQuery expressions can contain references directly to the filesystem (as in 'doc("info.xml")//node/text()'), neither XML_FILE or XML_ATTR need be set. At least one XQUERY_* must be specified. Users may take a result set from an XQuery and join it together in a couple of ways (using EXTRACT_MODE and EXTRACT_TYPE), or may return separate features for every element in the result-set (using EXTRACT_MODE). The XQueryFactory supports the XQuery Update Facility 1.0 Candidate Recommendation. If the XQUERY_* clause names an XQuery expression that should be parsed and evaluated as an update the clause USE_W3C_UPDATE_EXTENSIONS must be set to 'yes'. An update expression either returns results, or performs an update but not both. For this reason, it is not recommended to specify the update capabilities for the factory unless the query is performing an update as the resulting output may be inferior. For example, the elements of a result-set that is returned will be concatenated together. When the update capabilities are not being used more options are available for handling the result-set. FME Specific XQuery Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are several FME specific functions which can be used within an XQuery expression. These functions can get an attribute value from a feature, set a feature attribute value and test whether a feature has a value for a given attribute. fme:has-attribute This function tests whether or not the current feature has a value for a given attribute name. It takes a single parameter, which must be a string containing the name of the attribute. This function returns a boolean value indicating the existence of the attribute. fme:has-attribute( "parcel_id" ) This function can be used in conjunction with the fme:get-attribute function to conditionally output data, depending on the existence of an attribute. if( fme:has-attribute( "parcel_id" ) ) then {fme:get-attribute( "parcel_id" )} The parameter to this function does not have to be a string constant. Any XQuery expression which evaluates to a string can be used. The built-in XQuery data function can be useful when converting XML attributes and nodes to strings. fme:has-attribute( data( item/@name ) ) fme:get-attribute This function returns the value of an attribute on the current feature. The first parameter to this function must always be a string containing the name of the attribute whose value is to be retrieved. The second parameter is optional, and contains a default value which will be returned if the named attribute does not exist on the current feature. If no default value is provided and no attribute value exists, this function will return an empty sequence. The following example returns the value of the parcel_id attribute, or an empty sequence if the attribute does not exist on the current feature. fme:get-attribute( "parcel_id" ) This example returns the value of the parcel_id attribute, or a default value of 42 if the attribute does not exist on the current feature. fme:get-attribute( "parcel_id", 42 ) Note: The default value can be any atomic type: strings, floating point numbers, integers, etc. fme:get-attribute( "parcel_id", 3.14159 ) fme:get-attribute( "parcel_id", "default string value" ) fme:get-xml-attribute Similar to the fme:get-attribute function, this function returns the value of an attribute on the current feature. However, this function will attempt to parse the attribute value as XML, and returns a document node containing the parsed data. Given the same attribute name, the fme:get- attribute function would return a string containing escaped XML text (for example, a < would become <). This function only takes one parameter - the attribute name. Unlike the fme:get-attribute function, it does not accept second parameter containing a default value. Suppose the id attribute contains the following XML fragment: acdf-1278 We can use the following query to insert the XML fragment into a larger document. {fme:get-xml-attribute("id")} This produces the following XML document: acdf-1278 If the query had used the fme:get-attribute function, rather than the fme:get-xml-attribute function, we would have obtained the following XML document: <id>acdf-1278</id> fme:get-list-attribute This function is similar to the fme:get-attribute function, except that it operates on list attributes. The first parameter to this function must be the name of the list attribute whose contents are to be retrieved. The second parameter is optional, and if present, will be used as a delimiter between the values of the list attribute. If the second parameter is not present, the contents of the list attribute will be returned as a sequence of individual items. If the second parameter is used, the contents of the list will be returned as a single string, with the string value of the second parameter used as a delimiter. If a feature has a list attribute name list, then either of the following function calls may be used to extract the attribute contents: fme:get-list-attribute( "list" ) fme:get-list-attribute( "list{}" ) The function may also be used to access the contents of nested list attributes. For example, fme:get-list-attribute( "list{}._creation_instance" ) The second parameter provides a delimiter value. The function call fme:get-list-attribute( "list", "|" ) will return something similar to "1|2|3". fme:get-xml-list-attribute This function combines the fme:get-xml-attribute and fme:get-list- attribute functions. As with the fme:get-list-attribute function, this function will return the value of a list attribute. It willl attempt to parse each list element as XML text. This can be particularly useful when aggregating multiple XML fragments into a single larger document. This function also accepts a second parameter, which is a delimiter. For this function, the delimiter may be any XQuery item. For example, if the factory is being used to generate an HTML document, it may be useful to pass in a
element as the delimiter. fme:set-attribute This function sets the value of an attribute on the current feature. As with the other FME specific functions, the first parameter must be a string containing the attribute name. The second parameter contains the attribute value. This function always returns an empty sequence. The second parameter can have nearly any type. All atomic types are accepted, and some node types. If a particular type is not accepted, casting to a string, or using the data function may succeed. For example: fme:set-attribute( "pi", 3.14159 ) fme:set-attribute( "dept", data( item/@dept ) ) fme:set-attribute( "string_attr", "string value" ) If an XML node is passed as the second attribute, a string containing its XML representation will be set as the attribute value. It will not be a string escaped into XML escape character entities. fme:set-attribute( "node_attr", parcels/parcel ) If you wish to set multiple attributes within the same XQuery expression, the best method is to use a sequence of function calls. For example: let $xmin := min(points/point/@x) let $xmax := max(points/point/@x) let $ymin := min(points/point/@y) let $ymax := max(points/point/@y) return ( fme:set-attribute( "xmin", $xmin ), fme:set-attribute( "xmax", $xmax ), fme:set-attribute( "ymin", $ymin ), fme:set-attribute( "ymax", $ymax ) ) Since the set-attribute function returns an empty sequence, the return value of the query is an empty sequence. When run with such a query, the factory will output a warning about the empty return value. This can be safely ignored, or can be eliminated by appending a dummy constant value to the end of the sequence. fme:set-list-attribute This function is similar to the fme:set-attribute function, except that it operates on list attributes. The first parameter to this function is the name of the list attribute to be set. The second parameter contains the attribute value. This function always returns an empty sequence. The second parameter may be of nearly any type, and may be a sequence of any length including the empty sequence. As with fme:set-attribute, all atomic types are accepted and some node types. If a particular type is not accepted, casting to a string, or using the data function may succeed. If a sequence of XML nodes is passed as the second attribute, their XML representation will be set as the list attribute values. It will not be a string escaped into XML escape character entities. The following will set the list attribute values to be each child of the parcels node: fme:set-list-attribute( "node_attr", parcels ) Since the set-list-attribute function returns an empty sequence, the return value of the query is an empty sequence. When run with such a query, the factory will output a warning about the empty return value. This can be safely ignored, or can be eliminated by appending a dummy constant value to the end of the sequence. Accessing Mapping File Macros ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is possible for a query to retrieve the values of mapping file macros. When the XQueryFactory is created, the values of all mapping file macros are stored as variables in the query context. While these variables are not read- only, changing them will not affect the values of the macros. Any changes will be lost when the query finishes executing. Each macro is bound to a variable which shares its name. These variables are all in the namespace referenced by the 'fme' prefix. Thus, the value of the FME_MF_DIR macro will be stored in the $fme:FME_MF_DIR variable. These variables may be used in the same way as any other XQuery variables. Clauses XML_FILE When this value is set the file is assigned as the target of the query. For a regular XQuery, the result set will be returned as a (set of) values. If performing an XQuery Update, then there is no result, and the query will result in an update directly to the file. Default: None Example:XML_FILE "info.xml" XML_ATTR Specifies the input attribute name. The contents of the attribute on a feature should be a valid XML document. Default: None Example: XML_ATTR xml_string XQUERY_FILE Specifies a file whose content is a valid XQuery document Default: None Example: XQUERY_FILE query.xqr XQUERY_ATTR Specifies the name of an attribute whose content on the current feature is a valid XQuery document/expression. Default: None Example: XQUERY_ATTR xquery_string XQUERY_EXPR Specifies an XQuery expression/document directly. This clause is useful when the user wishes to apply a simple XQuery expression (possibly just an XPATH 2.0 expression) to every feature that goes through the factory. A limitation of this clause (over the XQUERY_FILE or XQUERY_ATTR clauses) is that the value of the XQUERY_EXPR clause must be in the system encoding. Default: None Example: XQUERY_EXPR '//geom/point' MODE (SINGLE_FEATURE|DYNAMIC_XML|DYNAMIC_QUERIES) Specifies the way XML and XQUERY documents will be supplied to the factory. In SINGLE_FEATURE both documents are updated (since all information is available from the single feature). With DYNAMIC XML, only the XML document is updated. With DYNAMIC_QUERIES the XML document is not updated, but the XQuery documents are. Default: SINGLE_FEATURE Example: MODE SINGLE_FEATURE RESULT_ATTR Specifies the output result attribute name. The exact form of the attribute may differ depending on the EXTRACT_TYPE option Default: None USE_W3C_UPDATE_EXTENSIONS (yes|no) Specifies whether or not the queries are to be parsed and evaluated with the W3Cs XQuery Update Facility. Note: This should only be set to 'yes' if you are in fact processing an update. Default: no COPY_INPUT_ATTRS (yes|no) Specifies whether or not the input feature's attributes should be copied to any exploded output features. Only used if EXPLODE_MODE is set to 'yes' Default: no REMOVE_SOURCE_XML_ATTR (yes|no) Specifies whether or not the input feature's XML source attribute should be copied to any output feature(s). Only used if the XML source is an attribute. Default: no QUERY_SEPARATOR Specifies the string used to separate the result sets of separate queries from one another Default: '|' Example: QUERY_SEPARATOR ## RESULTS_SEPARATOR Specifies the string used to separate the result sets of a query. Default: ',' Example: RESULTS_SEPARATOR | EXTRACT_MODE (yes|no) When this clause is set to 'yes', the results of the queries are written onto the input feature, and it is sent out of the QUERY_RESULTS port When the EXTRACT_MODE clause is set to 'yes', the factory will evaluate the XQuery expression and place the result as an attribute specified by RESULT_ATTR. If there are multiple results, the results are concatenated together in the manner specified by the EXTRACT_TYPE parameter. If the EXTRACT_TYPE parameter is set to 'STRING', the results are simply concatenated together. This is useful when you are, for example, constructing a new XML document from an existing one. If the EXTRACT_TYPE parameter is set to CSV, the RESULTS_SEPARATOR parameter is used to separate the results, with the default value for this parameter being the comma character (','). In the case that multiple XQuery expressions are defined, the results from individual queries are concatenated together using the QUERY_SEPARATOR parameter as the separator. The default value for the QUERY_SEPARATOR is the pipe character ('|'). Default: None EXTRACT_TYPE (STRING|CSV) This clause specifies the shape of the results strings when the EXTRACT_MODE is set to 'yes'. CSV: Results are joined together into a CSV using the RESULTS_SEPARATOR, and these CSVs are assembled into a complex CSV using the QUERY_SEPARATOR. STRING: The results are simply concatenated together into a single string. This is useful if the query is intended to construct a valid XML document. Default:CSV EXPLODE_MODE (yes|no) When this clause is set to 'yes', the results of the queries are written into separate features for every result returned. These features are output from the factory via the QUERY_RESULTS port When the EXPLODE_MODE clause is set to 'yes', the factory will create new features for each element in the result-set of the XQuery expression. For example, an XQuery expression might just be an XPath 2.0 expression, in which case each node in the result set would be serialized and the resulting XML placed in the RESULT_ATTR attribute. Default: None WRITE_HEADER (yes|no) When this clause is set to 'yes', the XML header is written onto the output results. Note: This does not affect XQuery Updates on files. Default: yes SIMPLIFY_ON_SINGLE (yes|no) When this clause is set to 'yes', and there is only a single extracted value, and the EXTRACT_TYPE is set to CSV then treat the EXTRACT_TYPE as STRING if there is only a single result for all queries. Default: no STATIC_QUERY (yes|no) When this clause is set to 'yes', if no input features are read then the factory will assume that the XQuery and XML documents are defined statically (either as files or literal expressions). Default: no Output Tags The XQueryFactory supports the following output tags. QUERY_RESULTS If an XQuery expression has been evaluated successfully, any results of this expression will be output through this tag. INVALID If a feature failed at any stage of processing (e.g. invalid XQuery expression, malformed XML), it will be output through this tag. TO BE RESOLVED CSV_LIST and LIST added to Syntax section above as EXTRACT_TYPE parameters, but not documented.