Re: [xsl] having a template remember not to call itself again

Subject: Re: [xsl] having a template remember not to call itself again
From: "Graydon graydon@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 5 Mar 2023 16:40:00 -0000
On Sun, Mar 05, 2023 at 04:20:36PM -0000, Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx scripsit:
> Is there a more elegant way to handle this that am missing?

In XSLT, the order of execution is not known.

The result document will be ordered so that the document order of the
result nodes matches the document order of the source nodes which
produced the result nodes, but you don't know anything about how this
happens.

It looks a lot like you're trying to control order of execution, which
means you're stuck actively fighting XSLT.  (XSLT tends to win.)

You're also producing complex conditionals, which is usually an
indication that you're trying to do too much at once.

The XSLT 2 approach is modes:

<xsl:variable name="pass1" as="document-node()">
    <xsl:document>
        <xsl:apply-templates select="/*" mode="pass1things" />
    </xsl:document>
</xsl:variable>
<xsl:variable name="pass2" as="document-node()">
    <xsl:apply-templates select="pass1" mode="pass2things" />
</xsl:variable>

And you put the templates for each stage in their own mode.  You want to
keep individual modes as focused and uncomplicated as you can; it's
generally much better to have two modes than complex conditions.

The XSLT 3 approach is the transform function, where you write
individual stylesheets for each step and call them:

<xsl:variable name="pass1" as="document-node()">
        <xsl:sequence select="
            transform(map {
              'stylesheet-location': 'pass1.xsl',
              'source-node': /*
            }
            )?output" />
</xsl:variable>

<xsl:variable name="pass2" as="document-node()">
        <xsl:sequence select="
            transform(map {
              'stylesheet-location': 'pass2.xsl',
              'source-node': $pass1
            }
            )?output" />
</xsl:variable>

And so on.

This has the advantage of avoiding risks of mode leakage (accidentally
re-using mode names, default templates applying where you didn't expect,
etc.) and giving you individual stage stylesheets that can be run and
debugged on their own.  The disadvantage is you're going to have to make
friends with transform(), which is very similar to any other run-XSLT
process but you'll have to figure out how to express what you want in
map notation.


-- 
Graydon Saunders  | graydonish@xxxxxxxxx
^fs oferiode, pisses swa mfg.
-- Deor  ("That passed, so may this.")

Current Thread