[xsl] Legibility, repetition, nesting

Subject: [xsl] Legibility, repetition, nesting
From: "David Birnbaum djbpitt@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 20 Jul 2020 17:03:55 -0000
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

Current Thread