Mapping
This standardized format allows mappings to be configured consistently throughout primedocs — for example to map source fields of a data source to primedocs target fields.
Examples:
<Mapping>
<Map Source="fname" Target="Forname" />
<Map SourceValue="Hanna" Target="Forname" />
<Map SourceValue="Muster" Target="LastName" When="source('test') === 'someValue'" />
<Map SourceExpression="25*78" Target="Calculator" When="target('LastName') === 'Muster'" />
<Map>
<Map.Source>fname</Map.Source>
<Map.Target>Vorname</Map.Target>
</Map>
<Map>
<Map.SourceValue>Hanna</Map.SourceValue>
<Map.Target>Firstname</Map.Target>
</Map>
<Map>
<Map.SourceValue>Muster</Map.SourceValue>
<Map.Target>LastName</Map.Target>
<Map.When><![CDATA[source('test') < 12]]></Map.When>
</Map>
<If Condition="source('test') === 'someValue'">
<Map>
<Map.SourceExpression>25*78</Map.SourceExpression>
<Map.Target>Calculator</Map.Target>
</Map>
</If>
</Mapping>
JavaScript
Within a mapping you can use simple declarative statements or implement more complex logic via JavaScript.
Properties as elements or attributes
All of the following element properties can be set either as an attribute or as an element.
As an attribute:
<ElementName AttributeName="attribute content">
further element content
</ElementName>
As an element:
<ElementName>
<ElementName.AttributeName>attribute content</ElementName.AttributeName>
further element content
</ElementName>
For the If element with the Condition property, the following two configurations have exactly the same meaning:
<If Condition="source('LastName') === 'Muster'">
...
</If>
<If>
<If.Condition>source('LastName') === 'Muster'</If.Condition>
...
</If>
Map element
A Map element represents a single mapping operation. Exactly one source property and the Target must be set.
| Property | Description |
|---|---|
Source | By default: the name that identifies the value, e.g. the database column name in the Generic SQL provider. For XML data sources, see XML. If the value is not found, null is passed on. |
SourceValue | A constant value to be used. |
SourceExpression | A primedocs JavaScript expression that is evaluated. |
Target | The target property for the mapping. |
When | A primedocs JavaScript expression that executes the mapping conditionally. If it evaluates to true, the mapping is executed. |
If element
The If element allows conditions to be defined for entire blocks of mappings. If blocks can be combined and nested arbitrarily.
| Property | Description |
|---|---|
Condition | JavaScript condition — the result is checked for a truthy value. |
Conditions & expressions
Escaping
In XML, certain characters such as & or < have a special meaning and cannot be used directly. Escape them, e.g. & as &:
<Mapping>
<Map Source="Value" Target="Target" When="source('val1') === 'test1' && source('val2') === 'test2'" />
</Mapping>
Alternatively, the same can be achieved using CDATA and the element notation:
<Mapping>
<Map Source="Value" Target="Target">
<Map.When><![CDATA[source('val1') === 'test1' && source('val2') === 'test2']]></Map.When>
</Map>
</Mapping>
Source
Using the source API object, the source values can be accessed from JavaScript — analogous to the Source property of the Map element. If the value is not available, undefined is returned. The following example takes the last available phone number:
<Mapping>
<Map Source="Arbeitsplatz" Target="Phone" When="source('Arbeitsplatz') != null" />
<Map Source="Mobile" Target="Phone" When="source('Mobile') != null" />
</Mapping>
For compatibility reasons, the source API object can also be accessed via oo or OO.
Target
Using the target API object, previously mapped values can be accessed from JavaScript. If the value is not available, undefined is returned. The following example assembles an address:
<Mapping>
<Map SourceExpression="source('street')+' ' +source('hausnr')" Target="Street" />
<Map SourceExpression="target('street') + '\r\n' + source('PLZUndOrt')" Target="CompleteAddress" />
</Mapping>
Result:
Source
----------
street Teststrasse
hausnr 42
PLZUndOrt 4242 Testhausen
Result
----------
Street Teststrasse 42
CompleteAddress Teststrasse 42
4242 Testhausen
Main function
To run more complex JavaScript methods, the function main() can be defined, which is then called. The following example adapts a Swiss phone number to the international format:
<Mapping>
<Map Target="Phone">
<Map.SourceExpression>
function main()
{
// normalises all phone numbers
// 0715110500 => +41 71 511 05 00
// +41 71 511 05 00 => +41 71 511 05 00
var input = source('phonenumber').replace(/ /g, '');
var patt = /((\+|00)41|0)([0-9]+)/;
var matchArray = patt.exec(input);
var number = matchArray[3];
return "+41 " + number.substring(0,2) + " " + number.substring(2,5)
+ " " + number.substring(5,7)+ " " + number.substring(7,9);
}
</Map.SourceExpression>
</Map>
</Mapping>
StartsWith function
Often you want to check whether a text begins with certain characters — e.g. whether the text in ZIP_Code (postal code) starts with CH-.
The JavaScript startsWith function does not yet exist in ES5. The expression source('ZIP_Code').startsWith('CH-') can therefore not be evaluated. Working alternative:
source('ZIP_Code').indexOf('CH-') === 0
Notes
- In JavaScript, conditions are checked for a truthy value. Non-boolean values are also evaluated: positive numbers or non-empty strings count as true.
- JavaScript can distinguish between
nullandundefined. If a value is not available, theSourceproperty of theMapelement returnsnull, while thesourceAPI object returnsundefined. - Comparisons: the
==operator also compares different data types, e.g.'55' == 55evaluates to true. Sinceundefined == nullis also true,source('Name') == nullcan be used to check for both empty (null) and unavailable (undefined) values.
Mapping data source
Depending on the data source, the way the data is accessed differs — i.e. how the source value is passed in the Source attribute or in the source() function.
Default: key/value
Simple keys are specified — a direct mapping exists. Examples:
- column name for the SQL Address provider
- column name or column number for the CSV/XLSX Address provider
XML
For XML sources, an XPath (1.0) can be specified to identify the value:
| XPath result | Returned value |
|---|---|
| Attribute | Value of the attribute |
| Element | Content/value of the element |
| Text | The text |
| CData | Results wrapped in CData are returned without the CData tag. |
Example — XML source file
<Kontakt>
<Company>PrimeSoft AG</Company>
<Adresse>
<PLZ>8360</PLZ>
<City>Eschlikon</City>
<Street>Bahnhofstrasse 4</Street>
</Adresse>
<Contact>
<Option Type="Phone">+41 71 511 0 500</Option>
<Option Type="Mail">info@primesoft-group.com</Option>
</Contact>
</Kontakt>
Mapping
<Mapping Type="XML">
<Map Source="//PLZ" Target="Postleitzahl" />
<Map Source="/Kontakt/Adresse/City" Target="Stadt" />
<Map Source="//Street" Target="Strasse" />
<Map Target="KompletteAdresse">
<Map.SourceExpression>
source('//Company') + '\r\n' + source('//Street') + '\r\n' + source('//PLZ') + ' ' + source('//City')
</Map.SourceExpression>
</Map>
<Map Source="//Contact/Option[@Type='Phone']" Target="Telefon" />
</Mapping>
JSON
For JSON sources, a JSONPath can be specified to identify the value:
Example — JSON source file
{
"Kontakt": {
"Company": "PrimeSoft AG",
"Adresse": {
"PLZ": "8360",
"City": "Eschlikon",
"Street": "Bahnhofstrasse 4"
}
}
}
Mapping
<Mapping Type="JSON">
<Map Source="$.Kontakt.Adresse.PLZ" Target="Postleitzahl" />
<Map Source="$.Kontakt.Adresse.City" Target="Stadt" />
<Map Source="$.Kontakt.Adresse.Street" Target="Strasse" />
</Mapping>
Examples
If-Else
The current version has no Else section. For larger sections, the condition can be negated:
<Mapping>
<If Condition="source('Typ') === 'Geschäftlich'">
<!-- Map elements for the company address -->
</If>
<If Condition="!(source('Typ') === 'Geschäftlich')">
<!-- Map elements for the else case -->
</If>
</Mapping>
To select a value from several available elements, multiple Map elements with the same Target can be used:
<Mapping>
<Map Source="Privat" Target="Phone" />
<Map Source="Büro" Target="Phone" When="target('Phone') != null" />
<Map Source="Mobile" Target="Phone" When="target('Phone') != null" />
</Mapping>
Note the order: the Map elements are evaluated in sequence, i.e. the last available number is used.