Parameters in UDFs
When you create a user-defined function, you must specify what input parameters it should take (if any) and what output it should return. While input parameters are sometimes not necessary, an output parameter is mandatory in all cases, which means a function must always return something. For example, the function below has no inputs and one output which returns the text hello to the caller:
Function parameters can be of simple type (e.g., string or integer) or a complex structure. For example, the user-defined function FindArticle illustrated below has two input and one output parameters:
•POArtNr is an input parameter of simple type string;
•Amount is an input parameter of simple type integer;
•CompletePO is an output parameter of complex XML type.
The mapping above is available at the following path: <Documents>\Altova\MapForce2022\MapForceExamples\LookupArticle.mfd.
To add an input or output parameter, take the following steps:
2.Run the menu command Function | Insert Input or Function | Insert Output. Alternatively, click (Insert Input) or (Insert Output) in the toolbar.
3.Choose whether input or output parameters should be of simple or complex type (see dialog box above). See the list of available complex structures below. For example, to create a parameter that is a complex XML type, click Choose next to Structure and browse for the XML schema that describes the required structure.
If the function's mapping already includes XML schemas, they are available for selection as structures. Otherwise, you can select a new schema that will provide the structure of the parameter. The same is true for databases and other complex structures if they are supported by your MapForce edition. With XML structures, it is possible to select the root element for your structure if the XML schema allows it. To specify the root element, click Choose next to Root and select the root item from the dialog box that opens.
If selected, the check box Save structure file path relative to MFD file will change the absolute path of the structure into a path relative to the current mapping, when you save the mapping. For more information, see Using Relative Paths on a Component. The check boxes Input is required and Input is a Sequence are explained in the following subsections.
The structures on which a parameter in UDFs can be based are summarized in the list below.
MapForce Basic Edition:
•XML Schema Structure
MapForce Professional Edition:
•XML Schema Structure
MapForce Enterprise Edition:
•XML Schema Structure
•JSON Schema Structure
Input is required
To make a parameter mandatory in a user-defined function, select the Input is required check box (see dialog box above). When a parameter is mandatory, validation errors will occur if you do not connect an input to it. To make a parameter optional, clear the Input is required check box. In the main mapping, optional parameters have a slightly different appearance: their input connector (small triangle) has a dashed border.
You can also specify a default parameter value by connecting it to the default input of a parameter (see example below).
The default value will apply only if there is no other value. If the optional parameter receives a value when the function is called, that value takes precedence over the default.
Input is a sequence
You can optionally specify that a function's parameter should be treated as a single value (default option) or as a sequence. A sequence is a range of zero or more values. A sequence might be useful when your user-defined function expects input data as a sequence in order to calculate values in that sequence, for example, by calling functions such as avg, min, max. To treat the input of the parameter as a sequence, select the Input is sequence check box. Note that this check box is enabled only if the user-defined function is regular. Otherwise, the check box is disabled.
The usage of a sequence is illustrated in the following mapping: <Documents>\Altova\MapForce2022\MapForceExamples\InputIsSequence.mfd. In the extract of this mapping (see screenshot below), the data filter is connected to the user-defined function Calculate. The filter's output is a sequence of items. Therefore, the input parameter of the function is set to be a sequence.
Internally, the Calculate function aggregates all the sequence values: It runs the min, max, and avg aggregate functions on the input sequence (see screenshot below). To see the internal structure of the Calculate function, double-click the header of the Calculate component in the mapping above.
As a rule of thumb, the input data, either sequence or non-sequence, determines how often the function is called:
•When input data is connected to a sequence parameter, the user-defined function is called only once, and the complete sequence is passed into the user-defined function.
•When input data is connected to a non-sequence parameter, the user-defined function is called once for each single item in the sequence.
•If you connect an empty sequence to a non-sequence parameter, the function is not called at all. This can happen if the source structure has optional items or when a filter condition returns no matching items. To avoid this, use the substitute-missing function before the function input to ensure that the sequence is never empty. Alternatively, set the parameter to sequence and add handling for the empty sequence inside the function.
The Output is a Sequence check box may be required for output parameters, too. When a function passes a sequence of multiple values to its output component, and the output component is not set to sequence, the function will return only the first item in the sequence.
When a user-defined function has multiple input or output parameters, you can change the order in which parameters should appear to callers of this function. For example, the function below has three input parameters: input1, input2, and input3.
The order of parameters in the function's mapping (starting from the top) dictates the order in which they appear to callers of this function:
•Input and output parameters are sorted by their position from top to bottom. Therefore, if you move the input3 parameter to the top in the function's mapping, it will become the first parameter of this function.
•If two parameters have the same vertical position, the leftmost takes precedence.
•In the unusual case that two parameters have exactly the same position, the internal component ID is automatically used.