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:52:46 -0000
And, yes, I did forget something which is a minor improvement:  Can put
those dynamic matching templates in their own mode as well:

*<xsl:mode name="dynamic-mode" on-no-match="fail" />*
<xsl:template match="dm:inputs" *mode="dynamic-mode"*
xmlns:dm="dynamic:match">
    <xsl:param name="context" as="node()" />

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

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

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

which then requires the apply-template to reference that mode.

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

This way, everything is quite "C  la mode"!

On Wed, Mar 4, 2020 at 9:39 AM Alan Painter alan.painter@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> Another option is to take one of the tricks that Dimitre Novatchev
> employed in the excellent FXSL for XSLT2.0.
>
>
>
http://conferences.idealliance.org/extreme/html/2006/Novatchev01/EML2006Novat
chev01.html
>
> 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
> modes.
>
> <xsl:template match="dm:inputs" xmlns:dm="dynamic:match">
>     <xsl:param name="context" as="node()" />
>
>     <xsl:apply-templates select="$context" mode="inputs" />
> </xsl:template>
>
> <xsl:template match="dm:outputs" xmlns:dm="dynamic:match">
>     <xsl:param name="context" as="node()" />
>
>     <xsl:apply-templates select="$context" mode="outputs" />
> </xsl:template>
>
> (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" />
> </xsl:function>
>
> Now we can perform an apply-templates that matches templates in either of
> the modes:
>
> <xsl:apply-templates select="dm:matchElement($mode)"
> xmlns:dm="dynamic:match">
>     <xsl:with-param name="context" select="current()" />
> </xsl:apply-templates>
>
> where the variable 'mode' can be either "inputs" or "outputs" in this
> example.
>
> (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, https://www.delightfulcomputing.com/
>> Available for XML/Document/Information Architecture/XSLT/
>> XSL/XQuery/Web/Text Processing/A11Y training, work & consulting.
>> Barefoot Web-slave, antique illustrations:  http://www.fromoldbooks.org
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/552232> (by
> email <>)

Current Thread