I would consider approaching this with xsl:analyze-string
instead of replace
. The following will search for @anything@
substrings within the text and replace them with the matching property value (if such a property exists), leaving the rest of the text unchanged:
<xsl:template match="use_scheme_template" mode="expand_template">
<xsl:param name="template_id" select="@id_ref"/>
<xsl:param name="base_text" select="//scheme_template[@id=$template_id]"/>
<xsl:variable name="properties" select="property" />
<xsl:variable name="expanded_text">
<xsl:analyze-string select="$base_text" regex="@(.*?)@">
<xsl:matching-substring>
<!-- substitute the matching property value, if there is one,
or leave untouched if not -->
<xsl:value-of select="($properties[@id = regex-group(1)], .)[1]" />
</xsl:matching-substring>
<xsl:non-matching-substring>
<!-- leave non-matching parts unchanged -->
<xsl:value-of select="." />
<xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:value-of select="$expanded_text" disable-output-escaping="yes" />
</xsl:template>