How to Trim in xslt?
Asked Answered
W

5

15

I want to trim whitespace left and right in :
<xsl:value-of select="Datas/Data[@key='Name']/string"/>

How can I do that?

Wire answered 10/12, 2010 at 13:57 Comment(3)
Good question, +1. See my answer for a correct and easy solution using FXSL. :)Greataunt
I also updated my answer and explained how trim works.Greataunt
Anyone have an idea how to do this in XSLT 1.0 / XPath 1.0?Seligman
G
4

The easiest way is to use the trim template function of FXSL.

This transformation:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="trim.xsl"/>
<xsl:output method="text"/>

  <xsl:template match="/">
    '<xsl:call-template name="trim">
        <xsl:with-param name="pStr" select="string(/*)"/>
    </xsl:call-template>'
  </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<someText>

   This is    some text   

</someText>

produces the wanted, correct result:

'This is    some text'

How trim works:

It is easy to eliminate all starting whitespace characters in a string, but the difficult part is to eliminate all ending whitespace characters.

The FXSL's trim function/template achieves this by using another template/function of FXSL for reversing a string.

So, the processing goes like this:

  1. Eliminate leading white-space.

  2. Reverse the result.

  3. Eliminate leading whitespace.

  4. Finally reverse.

The full code for trim() in FXSL 2.0 (for XSLT 2.0) can be seen here. It is almost the same as the code for the trim template of FXSL 1.0 (for XSLT 1.0).

Greataunt answered 10/12, 2010 at 14:6 Comment(2)
I've just post another question about xpath I you have the time can you look if you have an ideaWire
@Christophe: I am just finishing breakfast and will be traveling to work. Will have a look in 2 hrs.Greataunt
D
16

normalize-space(Datas/Data[@key='Name']/string) might suffice, it will trim white space and the start and end. It does however also collapse any white space in between to a single space, I don't know whether you want that.

Durning answered 10/12, 2010 at 14:3 Comment(1)
@Dimitre it's not a trim but it answer at my probleme with whitespace. Thanks bothWire
G
4

The easiest way is to use the trim template function of FXSL.

This transformation:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="trim.xsl"/>
<xsl:output method="text"/>

  <xsl:template match="/">
    '<xsl:call-template name="trim">
        <xsl:with-param name="pStr" select="string(/*)"/>
    </xsl:call-template>'
  </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<someText>

   This is    some text   

</someText>

produces the wanted, correct result:

'This is    some text'

How trim works:

It is easy to eliminate all starting whitespace characters in a string, but the difficult part is to eliminate all ending whitespace characters.

The FXSL's trim function/template achieves this by using another template/function of FXSL for reversing a string.

So, the processing goes like this:

  1. Eliminate leading white-space.

  2. Reverse the result.

  3. Eliminate leading whitespace.

  4. Finally reverse.

The full code for trim() in FXSL 2.0 (for XSLT 2.0) can be seen here. It is almost the same as the code for the trim template of FXSL 1.0 (for XSLT 1.0).

Greataunt answered 10/12, 2010 at 14:6 Comment(2)
I've just post another question about xpath I you have the time can you look if you have an ideaWire
@Christophe: I am just finishing breakfast and will be traveling to work. Will have a look in 2 hrs.Greataunt
E
4

Offering another solution that I use in XSLT 2.0 since it's more concise and accurate (normalize-space is not a trim).

Use the replace function and a regular expression to grab the inner content minus the preceding and trailing whitespace.

replace(Datas/Data[@key='Name']/string,'^\s*(.+?)\s*$', '$1')
Exchange answered 19/7, 2012 at 23:32 Comment(0)
S
0

Compare the @ricosrealm's solution, for XSLT2 users, with the @Dimitre's for XSLT1 (and check also the number of lines of the FXSL-trim). The regular expression replace function is so simple, spend less CPU-time and less programmer's time.

For XSLT1 users in 2013

If you is a XSLT1 user, is probably because you not have choice to use XSLT2. Example: PHP depends on LibXML2 implementatin, that stoped in the 1999 standard, not implements the 2007's standard. Today (2013) only a fraction of XSLT1 users do this by performance considerations.

So, if you assumes that you is trapped by XSLT1 and your framework, is time to know and to use "registered functions", like on PHP (but any other like Python or Javascript using LibXML2 can use LibXML2's extensions), to approximate to XSLT2 liberty/functionality.
See XSLTProcessor::registerPHPFunctions on your language.

PHP example:

  <xsl:value-of 
       select="php:functionString( 'trim', Datas/Data[@key='Name']/string )"
  />

NOTE (edited): for non-libXML2 implementations, like at Microsoft (.NET) frameworks, as showed by @ChristopheDebove (comments below), there are also solutions for registered functions. Of course, for Java there are SAXON, the only good open source of XSLT2 today.

... If one day (see opinions about when here and here) you replace XSLT1 by XSLT2 in the same framework (ex. PHP), you not need to change your XSLT scripts, because is expected that registred functions will be the same.

Selfreliant answered 25/11, 2013 at 21:13 Comment(0)
F
0

You can make your own using only XSLT 1.0:

If only a trim is required, you can just implement it yourself like the following template. It calls itself recursively and strips away chars until the first and last char of the built-in XSLT function normalize-space() match the first and last chars of the remaining string. The two cases are basically left-trim and right-trim, with left-trim being done first (the outer otherwise case).

It might be a bit slow on large datasets but it works fine:

<xsl:template name="Trim">
<xsl:param name="value"/>
<xsl:choose>
  <xsl:when test="string-length($value)=0 or string-length(normalize-space($value))=0">
    <xsl:value-of select="$value"/>
  </xsl:when>
  <xsl:when test="starts-with($value,substring(normalize-space($value),1,1))">
  <xsl:choose>
    <xsl:when test="starts-with(substring($value,string-length($value)-1,1),substring(normalize-space($value),string-length(normalize-space($value))-1,1))">
    <xsl:value-of select="$value"/>
    </xsl:when>
    <xsl:otherwise>
    <xsl:call-template name="Trim">
    <xsl:with-param name="value" select="substring($value,1,string-length($value)-1)"/>
    </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
  </xsl:when>
  <xsl:otherwise>
  <xsl:call-template name="Trim">
    <xsl:with-param name="value" select="substring($value,2)"/>
  </xsl:call-template>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

Usage:

<xsl:call-template name="Trim"><xsl:with-param name="value" select="mynodehere"/></xsl:call-template>
Feltonfelts answered 15/5, 2020 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.