Subject: [xsl] how can I make non-tunnelling parameters tunnel through <xsl:next-match/>? From: "Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Fri, 1 Jul 2022 14:24:32 -0000 |
Hello everyone, The DITA Open Toolkit<https://www.dita-ot.org/> allows plugin stylesheets to be incorporated into processing via <xsl:import>. To keep my plugin code robust against future DITA-OT processing changes and other plugins, I call <xsl:next-match> and postprocess the results where possible. And XSLT 3.0 with shallow-copy moded templates make postprocessing pretty easy! I'm hitting a case where the existing code passes non-tunneling parameters from template A to B, with parameter defaults computed in template B. And when I try to wedge my processing between A and B using <xsl:next-match>, I can't get template B to properly receive parameters from A only when they're passed. For example, given the following XML input: <?xml version="1.0" encoding="utf-8" ?> <body> <note type="note">This is note 1.</note> <note type="caution">This is an important note 2.</note> <note type="unknown">This is some other note 3.</note> </body> and the original processing code: <?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" exclude-result-prefixes="#all" version="3.0"> <xsl:mode on-no-match="shallow-copy"/> <!-- A1 - default note --> <xsl:template match="note"> <xsl:apply-templates select="." mode="B"/> </xsl:template> <!-- A2 - Caution note --> <xsl:template match="note[@type = 'caution']"> <xsl:apply-templates select="." mode="B"> <xsl:with-param name="title" select="'Caution'"/> </xsl:apply-templates> </xsl:template> <!-- A3 - fallback for unknown note types --> <xsl:template match="note[@type = 'unknown']"> <xsl:apply-templates select="." mode="B"> <xsl:with-param name="type" select="'note'"/> </xsl:apply-templates> </xsl:template> <!-- B --> <xsl:template match="*" mode="B"> <xsl:param name="type" select="@type"/> <xsl:param name="title" select="'Note'"/> <!-- this is actually complicated string lookup code I don't want to replicate --> <span class="{$type}"><xsl:value-of select="$title"/>: <xsl:sequence select="node()"/></span> </xsl:template> </xsl:stylesheet> then the result is as follows: <?xml version="1.0" encoding="UTF-8"?><body> <span class="note">Note: This is note 1.</span> <span class="caution">Caution: This is an important note 2.</span> <span class="note">Note: This is some other note 3.</span> </body> The second element shows the "Caution" title computed in B, and the third element shows the "note" type passed from A3. But when I try to insert my own processing between A and B: <!-- B-prime --> <xsl:template match="*" mode="B" priority="10"> <!-- (priority emulates <xsl:next-match>) --> <xsl:param name="type"/> <xsl:param name="title"/> <!-- ...post-processing... --> <xsl:next-match> <xsl:with-param name="type" select="$type"/> <xsl:with-param name="title" select="$title"/> </xsl:next-match> </xsl:template> then note 1 and 2's type is empty because B-prime passes an empty sequence for the "type" parameter that bypasses B's default value. And if I remove the parameter stuff from B-prime, then the title for note 3 never gets through B-prime. How can I get sometimes-defined parameters passed through B-prime? Tunnelling is the correct solution, but the A and B templates (which I can't modify) do not define them as tunnelling parameters. I tried using <xsl:if> inside <xsl:next-match/> to selectively pass defined parameters, but it isn't allowed. I want B-prime to be as ignorant as possible about the outside world, but maybe that's not possible here. Thanks! ----- Chris Papademetrious Tech Writer, Implementation Group (610) 628-9718 home office (570) 460-6078 cell
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Thread | [xsl] XSL-List Guidelines, B Tommie Usdin btusd | |
Date | [xsl] XSL-List Guidelines, B Tommie Usdin btusd | |
Month |