For both the parameter and variable elements, if a value is assigned by the XPath expression, then one of the four basic XPath types will be returned: Boolean, string, number, or node set. When the value is given by using a non-empty template body, then a non-XPath data type is returned, and that will be a result tree fragment. XSLT adds one such type: result tree fragment. Thus,
<xsl:variable name="a">foo</xsl:variable>
<xsl:variable name="b">
<asdf/>
</xsl:variable>
both create RTFs, while
<xsl:variable name="c" select="1"/>
<xsl:variable name="d" select="'hello world'"/>
<xsl:param name="e"/>
do not. ($c is a number, $d a string, $e an empty string)
For example:
<xsl:variable name="myRtf">
<elem/>
<elem>hello</elem>
</xsl:variable>
The code above creates a result tree fragment and binds it to the variable myRtf, so XPath expressions can now refer to $myRtf when they want to use the
fragment. The fragment consists of 1 root node. That node has 2 'elem' element nodes as children, and one of those has a 'hello' text node as its child.
XSLT 1.0 imposes a fundamental limitation on result tree fragments: they can only be used in XPath expressions where strings can be used. Thus you can't
say $myRtf/elem[2]/text() to identify the 'hello' text node in the example above. You can say <xsl:copy-of select="$myRtf"/>, though. And
<xsl:value-of select="$myRtf"/> will work as you would expect it to. This will also work as it should, but not how you would expect:
<xsl:if test="$myRtf">... if you think of boolean($someNodeSet) youll see that it returns true when there is a node in the node-set; well, a
result tree fragment always has 1 node, so it's always true.