Maybe we don't need a new instruction for switching context. We could
re-use the @context-item attribute that already is allowed on
xsl:evaluate. If used on a non-xsl element, the attribute will become
@xsl:context-item.
A contrived example follows.
Consider this variable:
<xsl:variable name="baz" as="element(baz)">
<baz>
<bar>
<foo n="1"/>
<foo n="2"/>
</bar>
</baz>
</xsl:variable>
Then a template might create this output tree:
<xsl:for-each select="$baz/bar">
<td>
Count of foo elements in {path()}:
<xsl:value-of select="count(foo)"/>
</td>
</xsl:for-each>
(The stylesheet author preferred to switch context to $baz/bar in order
to "simplify" expressions.)
With @xsl:context-item, this can be written as:
<td xsl:context-item="$baz/bar">
Count of foo elements in {path()}:
<xsl:value-of select="count(foo)"/>
</td>
or in an xsl:message:
<xsl:message context-item="$baz/bar">
Count of foo elements in {path()}:
<xsl:value-of select="count(foo)"/>
</xsl:message>
On elements such as xsl:for-each and xsl:copy, @context-item will have
the same semantics as the existing @select attribute. Therefore it need
not be allowed on these elements. (Maybe xsl:copy/@select would have
better been named @context-item in the first place.)
Another example with xsl:choose:
<xsl:choose context-item="$baz/bar">
<xsl:when test="count(foo) = 2">...</xsl:when>
<xsl:otherwise>...</xsl:otherwise>
</xsl:choose>
This one combines @context-item with the @select attribute on xsl:when,
as proposed by Michael Kay at this year's XML Prague:
<xsl:choose>
<xsl:when context-item="$baz/bar"
test="count(foo) = 2" select="'two'"/>
<xsl:when test="count($baz/bar/foo) = 1">
<xsl:sequence select="'one'"/>
</xsl:when>
<xsl:otherwise>...</xsl:otherwise>
</xsl:choose>
I'm not sure though whether all occasions on which people use
xsl:for-each merely to switch context can be substituted with this
context-item attribute.
Sometimes the xsl:for-each instruction will comprise many result tree
elements or XSLT instructions. Then there is no single element to stick
the @context-item attribute onto.
The common case of one or more xsl:variable declarations in the new
context can be replaced by not switching context, but instead by
declaring the variables or the first variable with a @context-item:
<xsl:variable name="count" as="xs:integer" select="count(foo)"
context-item="$baz/bar"/>
<xsl:variable name="is-positive" as="xs:boolean" select="$count gt 0"/>
(Don't tell me that I don't need all these variables; this is a
contrived example.)
-- Gerrit
On 19.05.2020 14:00, Graydon graydon(_at_)marost(_dot_)ca wrote:
On Tue, May 19, 2020 at 08:53:54AM -0000, Pieter Masereeuw
pieter(_at_)masereeuw(_dot_)nl scripsit:
I would be very happy if I could make my intentions clearer by using a real
XSLT construct in this situation, such as *<xsl:with select="...">*. The
semantics could also help as an assertion that, indeed, the selection has
exactly length 1.
Despite a certain mad temptation to xsl:each-with, I think this might be
better as xsl:with-context.
I agree that the clarity would be an improvement. I wouldn't want to
see it force a single member sequence on the select, though.
-- Graydon
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--