Re: [xsl] today I learned <xsl:next-match/> does not automatically pass parameters to the next template

Subject: Re: [xsl] today I learned <xsl:next-match/> does not automatically pass parameters to the next template
From: "Imsieke, Gerrit, le-tex gerrit.imsieke@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 10 May 2023 15:22:48 -0000
That's an important observation, Chris. Since I discovered the same thing few years ago, I'm going full-tunnel for matching templates in most of my XSLT code that is likely to be imported and customized.

I'd try to convince the maintainers of the imported stylesheets to switch to tunnel attributes for all matching templates. Or file a pull request for it.

Gerrit

On 10.05.2023 15:53, Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx wrote:
Hi everyone,

Today I learned (after a couple hours of debugging) that <xsl:next-match/> does not automatically pass parameters to the next-matching template. I wanted to share this in case it saves someone else some trouble.

Given the following input document:

<root>

B <A/>

</root>

and the following stylesheet:

<?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 version="3.0">

B <!-- identity transform -->

B <xsl:template match="@*|node()">

B B B <xsl:copy>

B B B B B <xsl:apply-templates select="@*|node()"/>

B B B </xsl:copy>

B </xsl:template>

B <!-- push $in-root parameter into <A> -->

B <xsl:template match="root">

B B B <xsl:copy>

B B B B B <xsl:apply-templates select="@*|node()">

B B B B B B B <xsl:with-param name="in-root" select="'true'"/>

B B B B B </xsl:apply-templates>

B B B </xsl:copy>

B </xsl:template>

B <!-- use $in-root parameter inside <A> -->

B <xsl:template match="A">

B B B <xsl:param name="in-root" as="xs:string?"/>

B B B <xsl:copy>

B B B B B <xsl:attribute name="in-root" select="$in-root"/>

B B B B B <xsl:apply-templates select="@*|node()"/>

B B B </xsl:copy>

B </xsl:template>

</xsl:stylesheet>

I see that the $in-root parameter is passed from <root> into <A>:

<?xml version="1.0" encoding="UTF-8"?><root>

B <A in-root="true"/>

</root>

But if I add the following template:

B <!-- this blocks all non-tunneling parameters -->

B <xsl:template match="*" priority="10">

B B B <xsl:next-match/>

B </xsl:template>

then $in-root is blocked because I did not explicitly propagate it. And indeed, the XSLT 3.0 spec (6.8 Overriding Template Rules <https://www.w3.org/TR/xslt-30/#element-next-match>) describes this as expected behavior:

If a matching template rule R is found, then the result of the xsl:next-match or xsl:apply-imports instruction is the result of invoking R, with the values of parameters being set using the child xsl:with-param elements as described in 9.10 Setting Parameter Values.

This presented some difficulty in my case because I was using <xsl:next-match/> to incrementally modify the DITA-OT processing of many other templates with varying parameters. I canbt change those parameters to tunneling because Ibm trying to wedge into existing processing code. So, I will need to rethink my incremental processing approach.

Anyway, I hope this is helpful to someone.

* Chris

-----
Chris Papademetrious

Tech Writer, Implementation Group

(610) 628-9718 home office

(570) 460-6078 cell

XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/225679> (by email <>)

Current Thread