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
xmlns:xs=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
|