Re: [xsl] Avoiding dummy xsl:if with apply-templates

Subject: Re: [xsl] Avoiding dummy xsl:if with apply-templates
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sat, 12 Feb 2005 23:02:00 -0500
At 2005-02-13 03:53 +0000, Frans Englich wrote:
I find myself struggling with a construct I often need: conditionally, "else",
do something radically different depending on input.


For example:

           <xsl:variable name="el" select="elements" />
            <xsl:if test="count($el)">

But you don't need a variable above, test="location-path" will return false if the return is an empty node-set.


                <ul>
                    <xsl:apply-templates select="$el" />
                </ul>
            </xsl:if>

Here, the if statement and variable declaration exists solely to avoid an
empty ul element; the special condition which occurs when the select misses.

Producing xhtml tables is a similar case. I find these common situations in
XSLT programming.

These examples can be solved with usual conditional tests, as above, but I
want to push the conditionalis upon the engine and write with templates; the
clean, XSLT-like way. AFAICT, this made-up syntax would solve the problem:

<xsl:apply-templates select="elements">
        <ul>
                <xsl:apply/>
        </ul>
</xsl:apply-templates>

That isn't any more lines than:


 <xsl:if test="elements">
   <ul>
     <xsl:apply-templates select="elements"/>
   </ul>
 </xsl:if>

Hence, when the select clause fails, the apply-templates body is not entered,
and the conditionalis is not needed to be manually written and comes
naturally, even.

But on what are you trying to economize? It would seem you are overloading the <xsl:apply-templates> instruction, and it would be unclear where <xsl:with-param> and <xsl:sort> would sit, though I assume the <xsl:sort> would be a first child and the <xsl:with-param> would be a child of your suggested <xsl:apply/>. If you are economizing on source-node-tree accesses in order to do multiple <xsl:apply/>, that can be done with node-set variables as in your original starting point ... it isn't so very much more verbose or "unnatural". Also, what would be the current node list and current node for the <ul> in your above? So far in XSLT, every select="location-path" in an element always sets a new current node list for the duration of the element ... what if someone used an attribute value template in an attribute of the <ul> element ... to which node would that refer?


What is the proper way of doing what I want?

I think I've just written it above. It doesn't overload any of the existing XSLT semantics, doesn't change the effect of select= and the current node list, and is consistent with the need to build an unordered list only if there are elements with which it is to be built. A processor need not obtain all elements referred to in the test as it knows the semantics of the test= attribute and can return "true" at the first encounter of a return node.


I hope this is considered helpful.

...................... Ken


-- World-wide on-site corporate, govt. & user group XML/XSL training. G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995) Male Breast Cancer Awareness http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread