Re: [xsl] How do I pass the mode as a string?

Subject: Re: [xsl] How do I pass the mode as a string?
From: "Alan Painter alan.painter@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 4 Mar 2020 08:39:38 -0000
Another option is to take one of the tricks that Dimitre Novatchev employed
in the excellent FXSL for XSLT2.0.

This can be a way to work around the absence of higher-ordered functions in
the community editions of the XSLT processors.

The trick is to select your desired template by performing an
xsl:apply-templates against a generated "special" element.

For instance, in the original example, there are two desired modes and we
want to call either mode "inputs" or "outputs".
For illustration purposes, we can define those modes and the templates that
are declared for those modes:

<!-- templates for mode "inputs" -->
<xsl:mode name="inputs" on-no-match="fail" />
<xsl:template match="element()" mode="inputs" > .. </xsl:template>
<xsl:template match="attribute()" mode="inputs" > .. </xsl:template>

<!-- templates for mode "outputs" -->
<xsl:mode name="outputs" on-no-match="fail" />
<xsl:template match="element()" mode="outputs" > .. </xsl:template>
<xsl:template match="attribute()" mode="outputs" > .. </xsl:template>

(Not required to declare the mode, of course, but I like to do this in
order to set a fail in case I've missed a match condition somewhere.)

Now, the question is, how to match those modes "dynamically".  We can set
some other templates that cal  xsl:apply-templates themselves using these

<xsl:template match="dm:inputs" xmlns:dm="dynamic:match">
    <xsl:param name="context" as="node()" />

    <xsl:apply-templates select="$context" mode="inputs" />

<xsl:template match="dm:outputs" xmlns:dm="dynamic:match">
    <xsl:param name="context" as="node()" />

    <xsl:apply-templates select="$context" mode="outputs" />

(Can obviate the re-definition of the 'dm' namespace by declaring it within
the enclosing stylesheet or package element.)

Now, finally, we need to call these templates.  We need to be able to
perform an "apply-templates" on a "dm:inputs" element or a "dm:outputs"
element.  For this, we can use a helper function:

<xsl:function name="dm:matchElement"
as="element()" xmlns:dm="dynamic:match">
    <xsl:param name="localName" as="xs:string" />

    <xsl:element name="dm:{$localName}" namespace="dynamic:match" />

Now we can perform an apply-templates that matches templates in either of
the modes:

<xsl:apply-templates select="dm:matchElement($mode)"
    <xsl:with-param name="context" select="current()" />

where the variable 'mode' can be either "inputs" or "outputs" in this

(Again, can obviate the delcaration of the 'dm' namespace by declaring in
the enclosing stylesheet or package element.)

I've constrained the templates matching to "node()" values here but this
could work with "item()" values as well if I'm not mistaken.

Anyway, that's another twist that XSLT offers (even XSLT 2.0) which would
allow you to have the equivalent of being able to assign a mode dynamically.

Obviously, easier to do as higher-order-functions, but it's another tool
that's available in the community editions.

On Wed, Mar 4, 2020 at 3:07 AM Liam R. E. Quin liam@xxxxxxxxxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> On Tue, 2020-03-03 at 22:47 +0000, Wendell Piez wapiez@xxxxxxxxxxxxxxx
> wrote:
> > I am also hoping that Liam suggests generating the templates
> > dynamically, then using the transform() function to apply them.
> :-)
> Well, i mentioned shadow attributes because David Carlislebs assertion
> was no longer entirely true, which i thought it worth pointing out.
> Itbs true you could write an XSLT transform to create a stylesheet
> using a given mode, and then apply it, all in-memoy, with
> fn:transform().
> But i prefer to keep things as simple and maintainable as possible!
> Liam
> --
> Liam Quin,
> Available for XML/Document/Information Architecture/XSLT/
> XSL/XQuery/Web/Text Processing/A11Y training, work & consulting.
> Barefoot Web-slave, antique illustrations:

Current Thread