Subject: Re: [xsl] having a template remember not to call itself again From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sun, 5 Mar 2023 18:18:16 -0000 |
With all due respect, this seems most likely the result of messy design/algorithm. There is nothing wrong in general to have the same template called many times in a chain of calls. And due to XSLT being a functional language, recursion is one often-used practice. Also, there are many examples where the same processing chain must be applied many times until the necessary precision is reached -- for example calculating the limit of a sequence or the sum of a series with desired precision. For recursive processing, my preferred way of maintaining full confidence that the recursion will end is totally similar to a mathematical induction proof. Yes, one must be able to **prove** that the algorithm is correct. That is: 1. It is a fact that some statement P is true (the algorithm produces the correct result) for a range of numbers, say 1 to N. 2. We can prove that if P is true for K, then it is true for K+1 Based on these two steps we conclude that P is true for all natural numbers. And if someone cannot perform a similar "proof" of their recursion algorithm, then this indicates that most likely there are flaws in the algorithm Thanks, Dimitre On Sun, Mar 5, 2023 at 8:20b/AM Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx < xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > Hi everyone, > > > > I have a stylesheet with many templates that must all chain together and > play nice with each other. So I write them in the following form: > > > > <xsl:template match="CONDITION1_HERE"> > > > > <!-- apply this template's processing first --> > > <xsl:variable name="result" as="element()"> > > ...PROCESSING1_HERE... > > </xsl:variable> > > > > <!-- apply subsequent self-or-children templates last --> > > <xsl:apply-templates select="$result"/> > > </xsl:template> > > > > When a template applies its processing first then calls other templates > last, I will call it btail-callb template chaining (although I donbt know > the correct term). > > > > For btail-callb chaining to work, PROCESSING1_HERE must transform the > content so that CONDITION1_HERE is not met again (or at least not met in a > way that loops infinitely). > > > > But, what if PROCESSING1_HERE is very complex (nested moded templates, > recursion, etc.) and sometimes CONDITION1_HERE will match after this > template was previously applied, and there is no practical way to embed the > complexity of predetermining PROCESSING1_HEREbs failure to remove the > condition into CONDITION1_HEREbs match expression? > > > > This could be avoided by using bhead-callb chaining: > > > > <xsl:template match="CONDITION2_HERE"> > > > > <!-- apply subsequent self-or-children templates first --> > > <xsl:variable name="result" as="node()*"> > > <xsl:next-match/> > > </xsl:variable> > > > > <!-- apply this template's processing last --> > > ...PROCESSING2_HERE... > > </xsl:template> > > > > But now, all bets are off on what PROCESSING2_HERE will encounter. Maybe > the result will have multiple elements, or be filtered out to zero > elements, or might have text() nodes interspersed due to reformatting and > styling templates. Maybe <xsl:next-match/> modified the content such that > CONDITION2_HERE isnbt even matched any more. PROCESSING2_HERE must handle a > much wider range of possible input, and the more templates that exist in > the stylesheet, the more varied the input from <xsl:next-match/> might be. > (I actually had all my templates written as bhead-callb chaining, and I am > converting them to btail-callb chaining due to such issues.) > > > > So now Ibm back to btail-callb chaining, and figuring out how to get a > template to not call itself when it fails to remove the condition > triggering the match. I tried setting a tunnelling variable that would give > a heads-up to the template not calling itself again: > > > > <xsl:template match="CONDITION1_HERE[not($CONDITION1_CALLED)]"> > > <xsl:param name="CONDITION1_CALLED" as="xs:boolean" select="false()" > tunnel="yes"/> > > > > <!-- apply this template's processing --> > > <xsl:variable name="result" as="element()"> > > b&PROCESSING1_HEREb& > > </xsl:variable> > > > > <!-- apply subsequent self-or-children templates --> > > <xsl:apply-templates select="$result"> > > <xsl:with-param name="CONDITION1_CALLED" as="xs:boolean" > select="true()" tunnel="yes"/> > > </xsl:apply-templates> > > </xsl:template> > > > > but the templatebs $CONDITION1_CALLED parameter is out-of-scope in its > match expression. > > > > So now the only solution I can think of is to put some kind of temporary > marker attribute in the matching element, then have a final document-down > cleanup pass to remove the markers. And if multiple templates need markers, > Ibll need to clean them all up. Icky. > > > > Is there a more elegant way to handle this that am missing? > > > > Thanks as always for your collective wisdom, and thanks for making it this > far! > > > > - 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/782854> (by > email <>)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] having a template remembe, Michael Kay mike@xxx | Thread | Re: [xsl] having a template remembe, Joel Kalvesmaki dire |
Re: [xsl] having a template remembe, Michael Kay mike@xxx | Date | [xsl] Selecting elements from sourc, Trevor Nicholls trev |
Month |