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: "Lizzi, Vincent vincent.lizzi@xxxxxxxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 10 May 2023 14:50:26 -0000
Hi Chris,

Thanks for sharing! It seems like there should be an optional attribute on
xsl:next-match to specify that you want to automatically propagate all
parameters.

Vincent

_____________________________________________
Vincent M. Lizzi
Head of Information Standards | Taylor & Francis Group
vincent.lizzi@xxxxxxxxxxxxxxxxxxxx<mailto:vincent.lizzi@xxxxxxxxxxxxxxxxxxxx>

From: Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Wednesday, May 10, 2023 9:54 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] today I learned <xsl:next-match/> does not automatically pass
parameters to the next template

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>
  <A/>
</root>

and the following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl=http://www.w3.org/1999/XSL/Transform<http://www.w3.org/1999/XSL/Tra
nsform>
xmlns:xs=http://www.w3.org/2001/XMLSchema<http://www.w3.org/2001/XMLSchema>
version="3.0">

  <!-- identity transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- push $in-root parameter into <A> -->
  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
        <xsl:with-param name="in-root" select="'true'"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!-- use $in-root parameter inside <A> -->
  <xsl:template match="A">
    <xsl:param name="in-root" as="xs:string?"/>
    <xsl:copy>
      <xsl:attribute name="in-root" select="$in-root"/>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </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>
  <A in-root="true"/>
</root>

But if I add the following template:

  <!-- this blocks all non-tunneling parameters -->
  <xsl:template match="*" priority="10">
    <xsl:next-match/>
  </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 can't change those parameters to
tunneling because I'm 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/194671> (by
email<>)


Information Classification: General

Current Thread