Re: [xsl] best practices for using XSLT modes

Subject: Re: [xsl] best practices for using XSLT modes
From: "Mukul Gandhi gandhi.mukul@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 5 Dec 2019 05:54:37 -0000
Hi Mike,

On Wed, Dec 4, 2019 at 4:14 PM Michael Kay mike@xxxxxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

([mukul] I assume, you mean 'mode' here) helps to modularise the logic, and
> in particular, for someone reading the code, if apply-templates uses a
> specific mode then it reduces the effort needed to find the template rules
> that might get invoked -- which is a significant part of the effort of
> debugging stylesheets.
>

In fact, this was the reason why I wrote an example mentioning modes.
Thanks for the explanation.


> then you wonder whether a conditional (e.g. xsl:choose) might not be more
> appropriate.
>

In fact, I had a third example in my mind as well where I wanted to use
xsl:choose to produce a similar result. Its mentioned below (this is schema
aware, and I use the Saxon option -val:strict),

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                         xmlns:xs="http://www.w3.org/2001/XMLSchema";
                         exclude-result-prefixes="xs"
                         version="3.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:import-schema>
       <xs:schema>
             <xs:element name="root">
                <xs:complexType>
                    <xs:sequence>
                         <xs:element name="a" maxOccurs="unbounded">
                             <xs:complexType>
                                 <xs:attribute name="val"
type="xs:integer"/>
                             </xs:complexType>
                         </xs:element>
                    </xs:sequence>
              </xs:complexType>
            </xs:element>
       </xs:schema>
    </xsl:import-schema>

    <xsl:template match="root">
       <result>
          <xsl:apply-templates select="a"/>
       </result>
    </xsl:template>

    <xsl:template match="a">
      <xsl:choose>
        <xsl:when test="@val gt 0">
          <val><xsl:value-of select="@val"/>: positive</val>
        </xsl:when>
        <xsl:when test="@val lt 0">
          <val><xsl:value-of select="@val"/>: negative</val>
        </xsl:when>
      </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

The above stylesheet, when given the same input XML, produces output,

<result>
   <val>-1: negative</val>
   <val>-4: negative</val>
   <val>5: positive</val>
   <val>3: positive</val>
   <val>2: positive</val>
</result>

(The order of "val" elements in this output, is different than what were
produced by my first two stylesheets. This could be fixed, if required)


> An interesting recent experience: we have a test driver for running XSLT
> tests, that's written in XSLT. The test assertions might take the form:
>
>       <result>
>          <assert>/res = 'Success'</assert>
>       </result>
>
> or
>
>       <result>
>          <any-of>
>             <assert>/res = 'Success'</assert>
>             <error code="XTSE0020"/>
>          </any-of>
>       </result>
>
> Now, firstly, we use a mode for evaluating assertions, that's separate
> from the mode used for processing other things in the test catalog. A good
> reason for that is that all the template rules in that mode return a
> boolean (indicating test success of failure), and the apply-templates call
> has to know that a boolean result is expected. The rules in a mode have to
> have equivalent pre- and post- conditions in terms of things like the
> expected parameters and the required return type, because they are
> interchangeable as far as the caller is concerned.
>
> Secondly, I found it useful recently to split the mode for evaluating
> assertions into two: one mode handles the case where the test produces a
> normal result, the other handles the case where it produces a dynamic
> error, and we issue a different apply-templates instruction for the two
> cases. The reason for this is that the two modes have different default
> behaviour (the mode that handles error outcomes returns "false" for all
> assertions except the one with match="error"): this change eliminated a lot
> of logic. Perhaps the same effect could have been achieved using a generic
> template rule delegating to specific template rules using next-match; but
> in this scenario where we're basically handling a two-dimensional decision
> tree (X - what is the outcome of a test?, Y - what is the assertion being
> tested?) then using modes for one of the dimensions and match patterns for
> the other can be useful.
>

Thanks, for sharing these experiences. Its enlightening to know.


> if you're writing complex stylesheets, modes are a powerful tool at your
> disposal and can be used with care to great effect.
>

I agree.



-- 
Regards,
Mukul Gandhi

Current Thread