Mike Kay Result Tree Fragment. Not a pretty name, and the
abbreviation RTF is unfortunate, but we have to live with
it.
When the body of an <xsl:variable> element is
evaluated (or "instantiated" to use the correct
jargon), the result is written to an RTF. There are only
three things you can do with an RTF: you can use xsl:copy-of
to copy it to the result tree (or to another RTF), you can
convert it implicitly or explicitly to a string, and you can
pass it to a function. There aren't any standard
functions that process RTFs, so in practice this means an
extension function.
SAXON and xt both provide extension functions to convert an
RTF to a node-set. This conversion can't be done
implicitly. The reason your xsl:for-each fails is that the
expression in the select attribute must yield a
node-set. Nothing else will do, in particular, it cannot be
an RTF.
David Carlisle adds:
A node set is what you get back from a select expression so
select="aaa[@xxx]|aaa[bbb]"
gives you the set of all elements with name aaa and either a
xxx attribute or a bbb child. Note this is a set not a list.
If some aaa element has both xxx attribute and bbb child,
you only get it once. The set is however ordered (in
document order, normally)
A node set is what you can apply templates to
<xsl:apply-templates select="aaa[@xxx]|aaa[bbb]"/> ie it's the relevant part of the input document (or some
secondary input document via the docyument() function)
A result tree fragment is what you produce in a template.
You can save it in a variable and while it has similar
structure to a node set (it's a bunch of XML nodes) it is
essentially opaque to XSL You can not apply templates to it
or interrogate its structure. The only thing you can do is
use xsl:copy-of to put the value of the variable holding the
result tree fragment into the result tree at some point.
xt and saxon (at least) have an extension function that
converts result tree fragments to node sets.
> <xsl:for-each select="$members"> members holds the result tree fragment, so you can't select
into it.
You could use
<xsl:for-each select="xt:node-set($members)"> Mike Brown adds:
You can identify *any combination* of unique nodes from
different places in the source tree, using an XPath
expression that selects the ones you want. Those nodes are
a "node set". They don't have to form a hierarchy or
anything.
You can create a new hierarchy of nodes (or multiple
hierarchies that are siblings of each other), using various
XSLT instructions and/or literal result elements. Those
nodes are a "result tree fragment". They're branches of a
tree.
So a result tree fragment *is* a set of nodes. It's just not
a "node set"
|