tags:

views:

1023

answers:

2

Does anyone know what XSL code would remove the trailing whitespace after the last word in an element?

<p>This is my paragraph.  </p>

Thanks!!

+1  A: 

Look at the normalize-space() XPath function.

<xsl:template match="p">
  <p><xsl:value-of select="normalize-space()" /></p>
</xsl:template>

Be careful, there is a catch (which might or might not be relevant to you):

[The function] function returns the argument string with whitespace normalized by stripping leading and trailing whitespace and replacing sequences of whitespace characters by a single space.

Tomalak
This solution isn't correct because besides removing the trailing whitespace, it removes other spaces, too.
Dimitre Novatchev
That's true. I guess this is better: http://www.stylusstudio.com/xsllist/200212/post10190.html
Tomalak
I emphasized the delicate bit in my answer. If it doesn't bother the OP, I guess normalize-space() is good enough.
Tomalak
it is not removing the spaces within the paragraph for me.
joe
@joe, normalize-space() removes all starting whitespace and all trailing whitespace. It also replaces every group of internal whitespace with a single space. You don't have starting whitespace and all internal whitespace is just one space. With another input there could be more (unexpected) changes.
Dimitre Novatchev
Unfortunately, the cited solution was one of my initial unsuccessful attempts at trim(). It doesn't work if the last non-space char is also present at other positions of the text. Also, trim() cannot be performed using a RegEx alone... :(
Dimitre Novatchev
Can it not? "^\s+|\s+$" should do the job.
Tomalak
Is this use of "|" standard RegEx syntax?
Dimitre Novatchev
@Dimitre Novatchev: Yes, it is. The pipe symbol defines an alternative - it is basically an "OR". The regex breaks down to plain English as "all white space at the start of the string OR all white space at the end of the string"
Tomalak
Then this is not at all what is needed, This matches the whitespace, but we need to skip this, not to match this.
Dimitre Novatchev
Wee just need to replace all matches with the empty string. :-)
Tomalak
+1  A: 

EDIT: Significant simplification of the code, thanks to a hint from Tomalak.

Here is an XPath 2.0 / XSLT 2.0 solution, which removes only the trailing spaces:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 >
  <xsl:output method="text"/>

  <xsl:template match="text()">
    "<xsl:sequence select="replace(., '\s+$', '', 'm')"/>"
  </xsl:template>
</xsl:stylesheet>

When this is applied on the following XML document:

<someText>   This is    some text       </someText>

the wanted result is produced:

"   This is    some text"

You can see the XSLT 1.0 solution (implementing almost the same idea), which uses FXSL 1.x, here:

http://www.biglist.com/lists/xsl-list/archives/200112/msg01067.html

Dimitre Novatchev
Would this regex "^\s+|\s+$" not work in XSLT?
Tomalak
@Tomalak Probably yes, but I need to look in the reference books. When I was answering I had just some free seconds, so this reflects my rather superficial RegEx knowledge.
Dimitre Novatchev
See my other comment.
Tomalak
@Tomalak You are right. This trims a string: replace(., '^\s+|\s+$', '', 'm') . The problem I know can't be achieved with RegEx is to say if a string contains balanced brackets.
Dimitre Novatchev