Templating workflow service

There is a subset of tasks that require substitution of several placeholders by provided values. Solving such tasks in XSLT is rather nonelegant.

<xsl:variable name="bodyText1" select="str:replace($bodyText, '$CustomerFirstName', @CustomerFirstName)" />
<xsl:variable name="bodyText2" select="str:replace($bodyText1, '$CustomerName', @CustomerName)" />
<xsl:variable name="bodyText3" select="str:replace($bodyText2, '$RentingStartDate', AS:FormatDate(@RentingStartDate, 'dd.MM.yyyy HH:mm'))" />
<xsl:variable name="bodyText4" select="str:replace($bodyText3, '$Object', AS:LookupValue('9b4c18af-12ad-4e05-8668-1cf448f899e7', @refRentalObjectId))" />
<xsl:variable name="bodyText5" select="str:replace($bodyText4, '$LocationAddress'
		, concat(AS:LookupValue('651cff99-00b2-461c-a792-1a766c865c54', @refBusinessUnitId)
		, ', ', AS:LookupValue('9d632a90-0470-4678-8516-977c69402143', @refBusinessUnitId)))" />
<xsl:variable name="bodyText6" select="str:replace($bodyText5, '$Location', AS:LookupValue('a392d1dc-519c-48b1-9f24-a3b8d9857337', @refBusinessUnitId))" />
<xsl:variable name="bodyText7" select="str:replace($bodyText6, '$TransactionNumber', @Number)" />
<xsl:variable name="bodyText8" select="str:replace($bodyText7, '$LesseeNote2', @LesseeNote2)" />
<xsl:variable name="bodyText9" select="str:replace($bodyText8, '$LesseeNote', @LesseeNote)" />
<xsl:variable name="bodyText10" select="str:replace($bodyText9, '$Logo', concat('&lt;img src=&quot;'
		,AS:GetConstant('Url'),'api/Organization/',@refOrganizationId,'/GetLogo&quot; alt=&quot;Logo&quot; width=&quot;200&quot;&gt;'))" />
<xsl:variable name="bodyText11" select="str:replace($bodyText10, '$Last6DigitsOfTransactionNumber', substring(@Number, string-length(@Number) -5))" />

Having an access to a templating engine in form of a workflow service could make solutions for such tasks easier/more readable/more elegant.

What about implementing it using XSLT? I think this could be implemented in ORIGAM.

Well, it actually expects the template to be tokenised already (using <span>).

But a recursive template would also do the job, I guess. It would do recursion as long as the source text would be different from the transformed text.

Designing the placeholders like this

Dear <name/>,

some text with other variables like <age/> or <name/> again

greatings <me/>

would make the XSLT much easier. You could then use standard matching template, e.g. <xslt:template match="name"> to handle those placeholders.