XSLT does not support XPath dynamic evaluation - therefore, you need to use an extension function such as EXSLT evaluate .
If you do not want to use the extension functions (and there are good reasons not to do this), another option is to request the input DOM document before performing the conversion and pass node -set to the conversion as a parameter.
Edit
About these curly braces: these are attribute value templates (AVT). They are semantically equivalent in an XSLT transformation:
<foo> <xsl:attribute name="bar"> <xsl:value-of select="XPathExpression"/> </xsl:attribute> </foo> <foo bar="{XPathExpression}"/>
The second is just a shortcut to the first.
About variables and parameters: Syntactically there is no difference between a variable and a parameter; where you reference $foo in an XPath expression, it will work the same if foo is defined by xsl:variable or xsl:param .
The difference between them is how they are populated. Variables are populated in the xsl:variable declaration. Parameters are declared in the named template using xsl:param , but they are populated with any calls to the named template using xsl:with-param , for example:
<xsl:call-template name="foo"> <xsl:with-param name="bar" select="XPathExpression"/> </xsl:call-template> <xsl:template name="foo"> <xsl:param name="bar"/> ...
The big exception to this are parameters that are a child of xsl:stylesheet . It is not possible to populate these parameters inside a transform they are filled from the outside, a transformation is called by some (environment-dependent) mechanism.
A fairly common use case is offset by the fact that XSLT does not have a system date function. So you will see something like:
<xsl:stylesheet ... <xsl:param name="system-date"/> ...
and then when calling the transform, something like this (in C #):
XsltArgumentList args = new XsltArgumentList(); args.AddParam("system-date", "", DateTime.Now.ToString("s")); xslt.Transform(input, args, result);