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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] How do I pass the mode as, Alan Painter alan.pa | Thread | Re: [xsl] How do I pass the mode as, Piez, Wendell A. (Fe |
Re: [xsl] How do I pass the mode as, Alan Painter alan.pa | Date | Re: [xsl] How do I pass the mode as, Piez, Wendell A. (Fe |
Month |