Re: [xsl] Legibility, repetition, nesting

Subject: Re: [xsl] Legibility, repetition, nesting
From: "Andre Cusson akhu01@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 26 Jul 2020 23:49:23 -0000
Why not just use apply-templates with dedicated templates with type
selectors (match), possibly using a mode? Use a for-each, if you need, to
set variables, call a named dispatch template, tunneling the parameter(s)
to it and the dispatch template simply does an apply-templates without the
need to pass the parameter(s), since they are available in the tunnel. All
the type specific processing is handled in each of the applied-templates.

Le dim. 26 juil. 2020 C  16:30, David Birnbaum djbpitt@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> a C)crit :

> Dear xsl-list,
>
> I am grateful to all of those who responded to my inquiry, below.
>
> Packaging the variables inside a map, as several readers suggested, so
> that I have to pass only one thing when I hand off responsibility from the
> general template (does the common stuff for all items) to the type-specific
> ones, reduces the repetition substantially, and calling a function to wrap
> up the variables, instead of doing it directly inside the template that
> does the calling, as readers also suggested, improves the legibility. So
> far, so good.
>
> I thought I had settled on using <xsl:next-match> to transfer control to a
> type-specific template for the type-specific processing as needed, but I
> ran into a problem because I was invoking <xsl:next-match> inside an
> <xsl:-for-each> (actually, two of them), and "using <xsl:for-each> makes
> the current template rule null" (Kay, p. 400). I hadnbt known about this
> limitation before, and if I have understood correctly, it seems to mean
> that I cannot use <xsl:next-match> inside <xsl:for-each>. I could move the
> entire for-each processing inside the next-match template, but then I'm
> repeating the same for-each code and common processing inside all of the
> next-match templates, and I'm trying to avoid repetition. Using template
> matching, rather than calling functions, is convenient because I have
> values for the type-specific templates like <xsl:template
> match="item[paradigm='1*a%1% B' 9']">, that is, values that cannot be used
> directly as XML names. Those values come from the original data, and
> although I could build a mapping table or function to translate them into
> XML names, it would be more legible, more self-documenting (to a developer
> who knows the data, that is, me), more convenient, and less error-prone to
> use them directly, as is possible with @match values like the one
> illustrated above.
>
> So: Is there a way I am overlooking for working around the inability to
> use <xsl:next-match> inside <xsl:for-each>, one that would let me, inside
> <xsl:for-each> use the original, data-driven <paradigm> values to identify
> where the type-specific processing should happen? Ideally the method would
> work with Saxon HE and without extension functions.
>
> Best,
>
> David
>
> On Mon, Jul 20, 2020 at 1:03 PM David Birnbaum djbpitt@xxxxxxxxx <
> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>> Dear XSL-list,
>>
>> I write here for advice about Best Practice. The question is at the end;
>> because I am constitutionally unable to be concise, the long narrative
>> before it is context.
>>
>> I'm developing an XSLT stylesheet that processes 134 different types of
>> items (same generic identifier, distinguished by an attribute value). For
>> each item, regardless of type, I create several variables, do an
>> <xsl:copy>, and inside that first create some other content that is common
>> to all items, regardless of type, and then use <xsl:choose> to handle the
>> types differently, according to their idiosyncrasies. I began by
>> implementing this as a single template with a long <xsl:choose> deeply
>> nested inside it, which has the advantage of avoiding unnecessary
>> repetition, since the shared operations are outside the <xsl:choose>. It
>> works, but perfectionism is a terrible curse ...
>>
>> Perhaps I'm being arbitrarily fastidious, but the <xsl:choose> inside the
>> deep nesting feels awkward; I wind up with one template that runs to more
>> than a thousand lines, where the <xsl:choose> is seven levels deep. This
>> made me wonder whether off-loading the type-specific tasks to separate
>> templates or functions, which could be called from the appropriate place,
>> would keep the main template down to a more manageable size. Specifically,
>> I'd like to be able to put the code blocks currently inside of the
>> <xsl:when> statements somewhere other than deep inside a single main
>> template.
>>
>> One implementation of this approach that works, but comes with its own
>> issues, is using an <xsl:next-match> with auxiliary lower-priority
>> templates that match item[@type eq 'x']. This lets me break out the
>> type-specific code into separate templates. The reason this is not wholly
>> satisfactory is that I have to pass all of the variables into these
>> separate templates as parameters, so I wind up repeating the same
>> <xsl:param> statements inside each of the secondary templates. That much
>> repetition feels suboptimal.
>>
>> The only approach that occurs to me that might simultaneously eliminate
>> repetition and avoid putting all of the processing inside a single
>> thousand-line template, most of which is the <xsl:choose> with all of the
>> type-specific handling inside <xsl:when> children, is to put the
>> type-specific processing into separate files, with an <xsl:when> root, and
>> then <xsl:include> them inside the <xsl:choose>. One downside seems to be
>> that they will not be valid XSLT (they wonbt have the necessary wrapper
>> boilerplate and the variables they use wonbt be defined inside them),
which
>> I think I could overcome by using an <oXygen/> "master document", which
>> would cause them to be validated in context. That isn't ideal, since it's
>> tied to a specific development environment, but since that happens to be
my
>> usual development environment, the objection is philosophical (= can be
>> ignored in the interest of Getting The Job Done), rather than practical.
>>
>> So: Is there a Best Practice approach to breaking out the type-specific
>> treatment of the different types of items that avoids both 1) unnecessary
>> repetition and 2) embedding a single thousand-line <xsl:choose>, which
>> contains all of the type-specific operations, seven levels deep inside a
>> template?
>>
>> Thanks,
>>
>> David
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3318727> (by
>> email)
>>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3035779> (by
> email <>)

Current Thread