Reputation: 67
I have a name field of length 30 as below:
<Name>Rainbow Charity </Name>
<Name>Ben Tromy Jig </Name>
I need to substring before the last space. So I need the below using xslt:
<Name>Rainbow Charity</Name>
<Name>Ben Tromy Jig</Name>
Upvotes: 1
Views: 368
Reputation: 243479
I. Here is a pure XSLT 1.0 solution:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Name/text()" name="trimRight">
<xsl:param name="pText" select="."/>
<xsl:choose>
<xsl:when test="not(substring($pText, string-length($pText)) = ' ')">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="trimRight">
<xsl:with-param name="pText"
select="substring($pText, 1, string-length($pText) -1)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the below XML document (derived from the OP-provided one, but with varying number of spaces in the intermediate whitespace segments):
<t>
<Name>Rainbow Charity </Name>
<Name>Ben Tromy Jig </Name>
</t>
The wanted, correct result is produced:
<t>
<Name>Rainbow Charity</Name>
<Name>Ben Tromy Jig</Name>
</t>
Do note: Unlike using normalize-space()
which removes all spaces but one from any longest contiguous substring containing only whitespace, this solution preserves all intermediate segments of spaces.
II. An XSLT 2.0 solution:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Name/text()">
<xsl:sequence select="replace(., '\s+$', '')"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the same XML document (above), the same correct result is produced:
<t>
<Name>Rainbow Charity</Name>
<Name>Ben Tromy Jig</Name>
</t>
Upvotes: 2
Reputation: 484
I agree with @michael.hor257k
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Name/text()">
<xsl:sequence select="normalize-space(.)" />
</xsl:template>
</xsl:stylesheet>
With input
<example>
<Name>Rainbow Charity </Name>
<Name>Ben Tromy Jig </Name>
</example>
produces
<example>
<Name>Rainbow Charity</Name>
<Name>Ben Tromy Jig</Name>
</example>
Upvotes: 1