FME Transformers: 2024.1

Categories
Format Specific
Web

Web

JSONTemplater

Populates a JSON document with FME feature attribute values. The document is provided as a template, and the transformer will use XQuery to insert attribute values and geometry information into the template.

The template may be loaded from an attribute, a file, or entered directly into the transformer parameters.

For each feature that enters the Root input port, the Root JSON template will be evaluated, and the result will be put into the attribute named by the Result Attribute parameter. The feature will then be output from the transformer.

A JSON template is simply a JSON document that contains XQuery functions. Essentially, these functions are placeholders for data values. When the template is processed, the functions will be evaluated, and the results will be inserted into the document. Most often this is used to insert feature attribute values into the document. The names of the attributes to be inserted are specified using the same XQuery functions used in several other transformers: XMLTemplater, XMLUpdater, XMLXQueryExtractor, XMLXQueryExploder, etc.

In the JSONTemplater, the fme:get-attribute, fme:get-list-attribute and fme:get-json-attribute functions are particularly useful. Only functions which do not alter the feature are permitted. See the XQuery Functions documentation for more information on the available functions.

The following JSON template populates a JSON element with the value of the ‘id’ feature attribute.

{

"id" : fme:get-attribute("id")

}

If the attribute does not exist on the feature, the JSON key value will have a null value.

To populate a JSON array with the contents of a list attribute, the fme:get-list-attribute may be used, as in this sample:

{

"ids" : [ fme:get-list-attribute("ids{}") ]

}

If the function call is not contained in the square array braces, an array will automatically be created if the function returns more than one value. An array will not be created if the function returns one or zero values.

Sub-Templates

When a template is evaluated, it can only access the attributes of the feature which is currently being processed. In order to allow a template to access the attributes of multiple features, the concept of sub-templates was introduced. Using the fme:process-features function, the transformer can evaluate a sub-template on a set of features, and then insert the results into the first template. In the transformer interface, each sub templates will be given a name. This name will then be used in the fme:process-features call to identify the sub-template to evaluate. In addition, a transformer input port will be created for each sub-template. The sub-template will be processed on features which enter the corresponding transformer input. Features which enter one of these input ports will be referred to as sub-features.

In the following example, the Root template constructs a JSON object representing a village, with information from a single feature. It then populates the “houses” value, using attribute values from features which entered the HOUSE input port.

{

"name" : fme:get-attribute("village_name"),

"populate" : fme:get-attribute("population"),

"houses" : [

fme:process-features("HOUSE")

]
}

The template associated with the HOUSE input port creates a house object.

{

"address" : fme:get-attribute("address"),

"owner" : fme:get-attribute("owner"),

"num_floors" : fme:get-attribute("num_floors")

}

If a single feature enters the Root input and two features enter the HOUSE input, the resulting JSON document could look like this:

{

"name" : "Anytown, USA",

"populate" : 2568,

"houses" : [

{

"address" : "123 Main Street",

"owner" : "John Doe",

"num_floors" : 2

},

{

"address" : "324 Main Street",

"owner" : "Jane Doe",

"num_floors" : 3

}

]

}

A template may call many sub-templates. For example, in the above example, we could add another sub-template named BUSINESS, and then used the process-features function to run this sub-template from the Root template. Additionally, a sub-template may run another sub-template, with the restriction that a sub-template may not directly or indirectly run itself.

Selecting the Sub-Features to Process

Often there is a hierarchical structure to the features that enter the JSONTemplater. For example, each village will have a number of houses, and each house will have several rooms, etc. If the fme:process-features function is used as described above, the resulting document will probably not be correct. Suppose there are two villages, each with five houses. Each village and house is represented by a separate FME feature. The village features are routed into the Root input port, while the house features are routed into the HOUSE input port.

If the transformer is run with the above templates, there will be two output features, as expected. However, both of the village objects will include all ten house objects. The correct behavior is to only evaluate the sub-template on the HOUSE features which correspond to the current village feature.

The fme:process-features function provides a way to do this. Additional function parameters may be used to filter the sub-features which are to be processed. The second parameter is a list of attribute names, and the third is a list of attribute values. Only sub-features whose attributes match the given list of attribute names and values will be processed.

This function call will evaluate the HOUSE sub-template on all HOUSE features whose village_id attribute matches the id attribute of the current feature.

fme:process-features("HOUSE", "village_id", fme:get-attribute("id"))

More than one attribute/value pair can be specified. In this case, the attribute names and attribute values have to be contained in parenthesis. The following function call will evaluate the HOUSE sub-template on all HOUSE features whose village_id attribute matches the id attribute of the current feature, and whose num_floors attribute is 2.

fme:process-features("HOUSE", ("village_id","num_floors"), (fme:get-attribute("id"), 2) )

Grouping Sub-Features

The Group Sub-Features By parameter allows for more coarse-grained filtering of sub-features than the parameters in the fme:process-features function. When this parameter is set to a list of attribute names, the fme:process-features function will only process sub-features which have the same values for these attributes as the feature currently being processed. Note that this parameter has no effect on the Root features. Each Root feature will be processed and output from the transformer.

When grouping sub-features, if all features in each group are consecutive, the performance of the transformer can be improved by setting the Grouped Sub-Features are Consecutive parameter to Yes. When this value is set, Root features will be processed as soon as all the applicable sub-features have arrived at the transformer. This means the transformer will operate in a non-blocking manner, rather than waiting for all features to arrive before starting to process templates. The behavior of the transformer is undefined if the features in a group do not all arrive consecutively. It is likely that some sub-features will not be processed if this happens.

Running Multiple Sub-Templates with a Single Function Call

It is possible to evaluate multiple sub-templates using a single function call. Simply pass a list of template names to the fme:process-features function. The sub-templates will be evaluated on each of the sub-features named in the list. The features will be processed in the order that they entered the transformer. The following function call processes the HOUSE and BUSINESS sub-templates:

fme:process-features( ("HOUSE","BUSINESS") )

The sub-feature selection parameters may still be used when the fme:process-features function is used to evaluate multiple sub-templates.

Running a Sub-Template on the Same Feature

It is possible to evaluate a sub-template using the same feature which is being used to evaluate the current template. The fme:process-template function takes a name, or list of names, of sub-templates which should be evaluated. These templates will be evaluated and the results will be inserted into the current template. To evaluate a template, just enter the name of the sub-template as a function parameter. For example, while a HOUSE feature is being processed, we could evaluate the OWNER template using the following function call. The OWNER template will be evaluated using the feature which entered the HOUSE input port.

fme:process-template("OWNER")

To evaluate a set of templates, pass a list of names:

fme:process-template( ("OWNER","ADDRESS") )

This technique may be used to modularize JSON templates, by moving repeated template structures into a single place. For example, if both houses and businesses have an address, the address could be extracted into an ADDRESS template, and the HOUSE and BUSINESS templates could then use the fme:process-template function to insert the address values. This way, the address template does not have to be duplicated inside the HOUSE and BUSINESS templates.

Geometry Templates

Geometry templates can be used to write out custom JSON geometry. There are a large number of functions which allow the extraction of geometric data, and the processing of sub-templates on geometries. For more information, see the XQuery Functions documentation for a list of all the geometry functions, and how to write out geometric data using sub-templates.

Geometry sub-templates operate in the same way as regular sub-templates, with the exception that a geometry sub-template does not create an input port on the transformer.

While a geometry template is being evaluated, the functions which access feature attributes (fme:get-attribute etc), are still usable.

Validation of Attribute and Sub-Template Names

When specifying a JSON template through the Template Expression parameter or the Template File parameter, the transformer will verify that all referenced feature attributes are present in an incoming feature. If attributes are missing (not exposed) from input features, the transformer will be highlighted red as incomplete. When this situation occurs, the transformer’s Summary Annotation will indicate the missing attributes the JSON template is referencing.

In addition, when sub-template names are passed to the fme:process-features and fme:process-template functions, the names will be validated to ensure they match the names given in the transformer interface.

This additional validation behavior can be overridden by setting the parameter Validate Attribute/Template Names to No.

Editing Transformer Parameters

Transformer parameters can be set by directly entering values, using expressions, or referencing other elements in the workspace such as attribute values or user parameters. Various editors and context menus are available to assist. To see what is available, click beside the applicable parameter.

For more information, see Transformer Parameter Menu Options.

FME Community

The FME Community is the place for demos, how-tos, articles, FAQs, and more. Get answers to your questions, learn from other users, and suggest, vote, and comment on new features.

Search for all results about the JSONTemplater on the FME Community.