[xsl] Whitespace text nodes near the front of mixed content

Subject: [xsl] Whitespace text nodes near the front of mixed content
From: "Trevor Nicholls" <trevor@xxxxxxxxxxxxxxxxxx>
Date: Tue, 6 Nov 2007 04:22:15 +1300
I'm struggling with a predicate or series of predicates that will pick out
certain text nodes. I have several stylesheets which generate HTML versions
of the input documents, but they generate unwanted whitespace in certain
circumstances. I'm afraid that they are XSL 1.0.

The input documents' DTD allows seven different elements (answer, cnote, dd,
ibody, li, step, td) to contain one or more target elements, along with
other mixed content. When we have something like the following fragment:

  <answer>
    <target/>
    <stuff>...</stuff>
    <otherstuff>...</otherstuff>
    <morestuff>...</morestuff>
  </answer>

then we get whitespace output for the whitespace text nodes which are
interspersed before, after and between the target and the various stuff
elements. Most of these are OK, but unfortunately the target element
generates no visible output and so whitespace nodes adjacent to a target
need to be suppressed - provided certain other conditions are met. The
problem involves any target(s) at the beginning of the answer (or cnote, or
dd, or ...).

I think the conditions are these (although it might be even more complicated
than I think):

A) If the current node is a whitespace text node whose parent is one of the
specified list of targetable elements (answer, cnote,...), AND

B1) If a whitespace text node precedes a target element then it should be
expressed if it has a preceding sibling (other than another target)
otherwise suppressed, OR

B2) If a whitespace text node follows a target element then it should be
expressed if there is an "earlier" NON-whitespace text node descendant of
the target's parent, otherwise (because we have still not generated any
visible output) it should be suppressed.

So:
  <xsl:template match="text()[normalize-space()='']
      [local-name(..)='answer'][????]" />

Starting with that "template" template, I obviously need to substitute
appropriate predicates for "????" in a series of suppressant templates, but
I've been frustrated by my attempts so far: it looks like position() isn't
going to be part of a working solution. And I'm sure there must be a better
way than having to spell out each one of the seven possible parents in a
separate pair of templates.

There are some remarkably clear-headed individuals on this list; can one of
them please put me out of my misery?

Cheers
Trevor

Current Thread