This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Possible MSXML 3 / 4 bug: using a for-each on xsl:variable / tre e-frag is misbehaving
- From: Jeni Tennison <jeni at jenitennison dot com>
- To: Jeff Beadle <Jbeadle at manh dot com>
- Cc: xsl-list at lists dot mulberrytech dot com
- Date: Tue, 14 May 2002 15:00:25 +0100
- Subject: Re: [xsl] Possible MSXML 3 / 4 bug: using a for-each on xsl:variable / tre e-frag is misbehaving
- Organization: Jeni Tennison Consulting Ltd
- References: <60A8664AEEB2D511B631000476AAB1A3E850F1@ma-atl81>
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi Jeff,
> Here's what I'm seeing: Within an xsl:for-each element, where the
> select is made against an xsl:variable tree-frag, xpath statements
> are failing to nodes outside of the given for-each's context.
I think you're seeing correct behaviour here. Within the xsl:for-each:
> <xsl:for-each select="msxsl:node-set($items)/item">
> <using_msxsl_node-set child-id="{@id}">
> <xsl:copy-of select="/xml/an-element"/>
> </using_msxsl_node-set>
> </xsl:for-each>
the current node is an item element within the node set derived from
the $items node set. The path /xml/an-element is resolved relative to
the current node -- the / means the root node of the node tree in
which the item resides.
The $items result tree fragment is generated with:
> <xsl:variable name="items" >
> <xsl:copy-of select="//item"/>
> </xsl:variable>
which means that the result tree fragment is a root node with a number
of item elements as children. The result tree fragment doesn't contain
any xml elements or an-element elements, so it shouldn't surprise you
that it doesn't return anything.
I think that perhaps you're expecting that / always gives you the root
node of the source of the transformation? That's not the case -- it
gives you the root node of the node tree of which the context node is
a part.
So to achieve what you want, store the root node of the source of the
transformation in a (global) variable:
<xsl:variable name="source" select="/" />
and then use that as the basis of your path within the xsl:for-each:
<xsl:for-each select="msxsl:node-set($items)/item">
<using_msxsl_node-set child-id="{@id}">
<xsl:copy-of select="$source/xml/an-element"/>
</using_msxsl_node-set>
</xsl:for-each>
---
In XPath 2.0, there's a new function called input() that returns the
node(s) that invoked the transformation. So in XSLT 2.0, you could do:
<xsl:variable name="items">
<xsl:copy-of select="//item" />
</xsl:variable>
<xsl:for-each select="$items/item">
<using_temporary_tree child-id="{@id}">
<xsl:copy-of select="input()/xml/an-element" />
</using_temporary_tree>
</xsl:for-each>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list