[xsl] Outputting White Space Only Nodes from Variables

Subject: [xsl] Outputting White Space Only Nodes from Variables
From: "Don Smith dsmith_lockesmith@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 22 Feb 2021 02:13:41 -0000
I'm receiving user input through an application and part of what the user can
input are generated text strings that can be placed above, before, after, and
below element content. So here's a simple example of the input XML:
<test>B  B <p class="title">Book Title</p>B  B <p class="heading">Chapter
1</p></test>
And here's how a transform to process the content will look with the
information about the generated text to use captured in variables:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"B  B 
xmlns:xs="http://www.w3.org/2001/XMLSchema"B  B 
exclude-result-prefixes="xs"B  B  version="2.0">
B  B  <xsl:output method="xml" indent="yes"/>B  B B B  B  <xsl:template
match="test">B  B  B  B  <output>B  B  B  B  B  B  <xsl:apply-templates/>B  B 
B  B  </output>B  B  </xsl:template>
B  B  <xsl:template match="*">B  B  B  B  <xsl:copy>B  B  B  B  B  B 
<xsl:copy-of select="@*"/>B  B  B  B  B  B  <xsl:apply-templates/>B  B  B  B 
</xsl:copy>B  B  </xsl:template>
B  B  <xsl:template match="p[@class='title']">B  B  B  B  <xsl:variable
name="generatedTextBefore" as="xs:string">A </xsl:variable>B  B  B  B 
<xsl:variable name="generatedTextAfter" as="xs:string?"> </xsl:variable>B  B 
B  B  <xsl:variable name="generatedTextAbove" as="xs:string">Short Stories
Collection</xsl:variable>B  B  B  B  <xsl:variable name="generatedTextBelow"
as="xs:string?">&#x0A;</xsl:variable>B  B  B  B  <xsl:variable name="class"
as="xs:string">B  B  B  B  B  B  <xsl:choose>B  B  B  B  B  B  B  B  <xsl:when
test="@class">B  B  B  B  B  B  B  B  B  B  <xsl:value-of select="@class"/>B 
B  B  B  B  B  B  B  </xsl:when>B  B  B  B  B  B  B  B 
<xsl:otherwise>none</xsl:otherwise>B  B  B  B  B  B  </xsl:choose>B  B  B  B 
</xsl:variable>B  B  B  B  <xsl:if test="not($generatedTextAbove = '')">B  B 
B  B  B  B  <xsl:message>ABOVE: Gen text value: |<xsl:copy-of
select="$generatedTextAbove"/>|</xsl:message>B  B  B  B  B  B  <xsl:element
name="pre">B  B  B  B  B  B  B  B  <xsl:attribute name="class"
select="concat($class, '_above')"/>B  B  B  B  B  B  B  B  <xsl:value-of
select="$generatedTextAbove"/>B  B  B  B  B  B  </xsl:element>B  B  B  B 
</xsl:if>B  B  B  B  <xsl:copy>B  B  B  B  B  B  <xsl:copy-of select="@*"/>B 
B  B  B  B  B  <xsl:if test="not($generatedTextBefore = '')">B  B  B  B  B  B 
B  B  <xsl:message>BEFORE Gen text value: |<xsl:copy-of
select="$generatedTextBefore"/>|</xsl:message>B  B  B  B  B  B  B  B 
<xsl:element name="gt">B  B  B  B  B  B  B  B  B  B  <xsl:attribute
name="class" select="concat($class, '_before')"/>B  B  B  B  B  B  B  B  B  B 
<xsl:value-of select="$generatedTextBefore"/>B  B  B  B  B  B  B  B 
</xsl:element>B  B  B  B  B  B  </xsl:if>B B B B B B B B B  B  <!-- output the
element content here -->
B  B  B  B  B  B  <xsl:apply-templates />B  B  B  B  B  B  <xsl:if
test="not($generatedTextAfter = '')">B  B  B  B  B  B  B  B 
<xsl:message>AFTER Gen text value: |<xsl:copy-of
select="$generatedTextAfter"/>|</xsl:message>B  B  B  B  B  B  B  B 
<xsl:element name="gt">B  B  B  B  B  B  B  B  B  B  <xsl:attribute
name="class" select="concat($class, '_after')"/>B  B  B  B  B  B  B  B  B  B 
<xsl:value-of select="$generatedTextAfter"/>B  B  B  B  B  B  B  B 
</xsl:element>B  B  B  B  B  B  </xsl:if>B  B  B  B  </xsl:copy>B  B  B  B 
<xsl:if test="not($generatedTextBelow = '')">B  B  B  B  B  B 
<xsl:message>BELOW Gen text value: |<xsl:copy-of
select="$generatedTextBelow"/>|</xsl:message>B  B  B  B  B  B  <xsl:element
name="pre">B  B  B  B  B  B  B  B  <xsl:attribute name="class"
select="concat($class, '_below')"/>B  B  B  B  B  B  B  B  <xsl:value-of
select="$generatedTextBelow"/>B  B  B  B  B  B  </xsl:element>B  B  B  B 
</xsl:if>B  B  </xsl:template>B  B B </xsl:stylesheet>
Given the above, what I'm wanting in the result document is this:
<output>B  B <pre class="title_above">Short Stories Collection</pre>B  B <p
class="title">B  B  B  <gt class="title_before">A </gt>Book Title<gt
class="title_after"> </gt>B  B </p>B  B <pre class="title_below"></pre>B  B <p
class="heading">Chapter 1</p></output>
But the variables with white space only content evidently get that content
stripped out. I've tried all of the following:
1. Use different instructions for the output of the variable: value-of,
copy-of, and sequence2. Created the variables as both strings and elements and
even RTFs3. Tried a character map4. Tried an alternative approach like using
strings "#SPACE, #TAB, #NL, etc. I know that would work but seems like it
should be unnecessary?
In every case the white space only variable content gets stripped out. How can
such content be output?
Thanks,
Don

Current Thread