Given a template used for building some html around a value, I want to pass in a string, rather than a node set. As an example I want to concat some values and pass that to the template. How can I achieve that sort of thing?
<xsl:template match="text()" mode="kvp-print-single">
<tr>
<td colspan="3"><xsl:value-of select="."/></td>
</tr>
</xsl:template>
...
<xsl:apply-templates select="concat=(haba/hiba:text(), ' - ', huba/baba:text())" mode="kvp-print-single"/>
ErrorMsg: xml or stylesheet file is invalid!
Exception: System.Xml.Xsl.XsltException: Expression must evaluate to a node-set.
You can't "pass in a string, rather than a node set" because templates are not called like functions. With XSLT, not the code controls the execution order but the data does by matching templates. It is possible to use named templates that can be called instead matched, but to pass values, you can use parameters for each templates.
In your case, you don't even have to as you can adress the text parts (given haba/hiba is the address) like so:
The adress needs to be correct XPath, of course (absolute or even relative to matching element).
@Mithon: The other answers require parameters. Use as many modularized templates as you want, but why would you want to add parameters if you don't need them?
You could use call-template and a named template, rather than apply-templates, thus:
The point of apply-templates is to take a nodeset, and apply the most appropriate template to each node in turn. call-template and named templates allows you to break up your XSLT into more manageable chunks, without changing the context.
If the aim is code re-use, to use the template in multiple places, then what you could do is give your template a name (in addition to the template match), and give it a default parameter
Then just use xsl:call-template to call it with you concatenated string as a parameter
Note, the template will still match "text()" nodes in the normal way when matched using xsl:apply-templates.