Q:

Trim white-spaces at the end of lines only before a specific tag

could you please help me?! I'm dealing with the following problem: the lines in my xml begin with the <lb> element. Some of these elements have an attribute <lb break="no">. I need to transform the line-by-line text into a floating text and also trim whitespaces before <lb break="no">, so that the word is written without spaces. At the same time it is necessary to leave all the whitespaces that are presented in the text, as there are many different tags that go one after another. If I'm using normalize-space() function, all of the whitespaces between the tags get lost and I need to write a test like this <xsl:if test="following-sibling::*[1][self::tei:span]">
            <xsl:text> </xsl:text> for every case.
How can I solve this?
I've found such a solution
<xsl:template match="text()">
    "<xsl:sequence select="replace(., '\s+$', '', 'm')"/>"
  </xsl:template>
but I don't know how to use such a code in my case.
Here is the sample text:
<p>
<lb n="3"/>Ich ergreife diese Gelegenheit eine Bitte an Sie zu rich 
<lb n="4" break="no"/>ten,<span type="inter" xml:id="GR55024-inter2">&#32;</span> zu <span type="inter" xml:id="GR55024-inter3">die</span> Sie mir<span type="inter" xml:id="GR55024-inter4">&#32;</span> die Aufmunterung durch das güti
<lb n="5" break="no"/>ge Versprechen gaben, <span type="inter" xml:id="GR55024-inter5">im Fall ich Bücher von der Je 
<lb n="6" break="no"/>naischen Bibliothek<ptr type="app" target="#GR55024-seite1-les1"/> nöthig haben sollte,</span> mir dieselben 
<lb n="7"/>gefälligst zu verschaffen. Ich <span type="inter" xml:id="GR55024-inter6">bedarf</span> jetzt zur Recen
<lb n="8" break="no"/>sion <span type="inter" xml:id="GR55024-inter7">des Buches</span> über <span type="inter" xml:id="GR55024-inter8">die</span> Verwandschaft der <span type="inter" xml:id="GR55024-inter9">griechischen 
<lb n="9"/>und deutschen</span> Sprache <span type="inter" xml:id="GR55024-inter10">das <hi rend="unterstrichen">Glossarium von</hi></span> <hi rend="unterstrichen"><persName key="">Hesychius</persName></hi>, 
<lb n="10"/><span type="inter" xml:id="GR55024-inter11">edit. Alberti &#x26; Ruhnkenii, und</span> <title type="werk" key=""><persName key=""><hi rend="unterstrichen">Corinthius</hi></persName></title>
<lb n="11"/>de dialectis, in der holländ. Ausgabe von <hi rend="unterstrichen"><persName key="">Koen</persName></hi>, <hi rend="unterstrichen">8<hi rend="unterstrichen">°</hi></hi> und 
</p> 

Thanks a lot!
I'm using the oXygen XML Editor and its XSLT-Debugger with Saxon 9.
Xslt template (not working)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xpath-default-namespace="http://www.tei-c.org/ns/1.0"
version="2.0">

<xsl:output method="xhtml" indent="yes"/>
<xsl:preserve-space elements="text"/>

<xsl:template match="/">
    <html>
        <head>
            <title>
                Title
            </title>
        </head>
        <body>
            <div>
            <xsl:apply-templates select="//div[@ana='ausfertigung']">
            </xsl:apply-templates>
            </div>
        </body>
    </html>
</xsl:template>

<xsl:template match="p">
    <p>
        <xsl:apply-templates/>
    </p>
</xsl:template>

<xsl:template match="p/text()">
    <xsl:text> </xsl:text>
</xsl:template>

<xsl:variable name="special-handling" select="text()
[following-sibling::*[1][self::lb[@break='no']]]"/>

<xsl:template match="text()[following-sibling::*[1][self::lb[@break='no']]]">
    <xsl:if test="$special-handling/ends-with(text(), '\n')"></xsl:if>
<xsl:value-of select="$special-handling/substring-before(text()[following-sibling::*[1]
[self::lb[@break='no']]],'\n')"></xsl:value-of>
</xsl:template>

</xsl:stylesheet>

The preliminary code that works found here
<xsl:template match="para/text()">
    <xsl:call-template name="selectWithoutBreaks"/>
</xsl:template>

Utilizes these templates:
<xsl:template name="selectWithoutBreaks" >
<xsl:variable name="linebreak">
    <xsl:text>
</xsl:text>
</xsl:variable>

<xsl:call-template name="replace-string">
    <xsl:with-param name="text" select="."/>
    <xsl:with-param name="replace" select="$linebreak" />
    <xsl:with-param name="with" select="''"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="with"/>
<xsl:choose>
    <xsl:when test="contains($text,$replace)">
        <xsl:value-of select="substring-before($text,$replace)"/>
        <xsl:value-of select="$with"/>
        <xsl:call-template name="replace-string">
            <xsl:with-param name="text" select="substring-after($text,$replace)"/>
            <xsl:with-param name="replace" select="$replace"/>
            <xsl:with-param name="with" select="$with"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$text"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

A:

You want special treatment for text nodes that are followed by 'lb' elements with break="no".  You want whitespace preserved in all other text nodes.  So:

Write an identity transform that preserves white space in content.
Add a template to match text nodes immediately followed by an lb element with break="no".  (Or alternatively in an existing template for text nodes, wrap the existing code in the xsl:otherwise clause of an xsl:choose element, and before it add an xsl:when element for the case where the text node is immediately followed by an appropriate lb element.
We need a name for the text nodes selected by your test; let's call them the special-handling text nodes.
If a special-handling text node ends with a newline, you want to strip it off.  Use ends-with() to test the condition, and substring() to perform the change.  (If you want to strip off multiple newlines at the end but leave all other whitespace untouched, you have a slightly more complicated task.)

