Reputation: 27
How to get substring of substring from xml node using xslt?
e.g.
input:
<node>This Is W3 School</node>
output:
<node>TIWS</node>
Here, I want to get first letter of each substring separated by space.
Upvotes: 0
Views: 11806
Reputation: 52888
If you're stuck with XSLT 1.0 you could use a recursive template call to process the string.
Example...
XML Input
<doc>
<node>This Is W3 School</node>
<node>One Two Three Four Five Six</node>
<node>Hello </node>
<node> X Y Z </node>
<node/>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<xsl:copy>
<xsl:call-template name="first_letters"/>
</xsl:copy>
</xsl:template>
<xsl:template name="first_letters">
<xsl:param name="input" select="normalize-space()"/>
<xsl:variable name="remaining" select="substring-after($input,' ')"/>
<xsl:value-of select="substring($input,1,1)"/>
<xsl:if test="$input">
<xsl:call-template name="first_letters">
<xsl:with-param name="input" select="$remaining"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
XML Output
<doc>
<node>TIWS</node>
<node>OTTFFS</node>
<node>H</node>
<node>XYZ</node>
<node/>
</doc>
Fiddle: http://xsltfiddle.liberty-development.net/6qVRKw1
Upvotes: 1
Reputation: 26
Thank you, for all your answers. As I am using xslt versio: 1.0 ,I have write substring functions to get desired output.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="node">
<node1>
<xsl:value-of select="substring(substring-before(normalize-space(substring-after(//node,'')),' '),1,1)"/>
<xsl:value-of select="substring(substring-after(normalize-space(substring-after(//node,'')),' '),1,1)"/>
<xsl:value-of select="substring(substring-before(normalize-space(substring-after(normalize-space(substring-after(//node,' ')),' ')),' '),1,1)"/>
<xsl:value-of select="substring(substring-after(normalize-space(substring-after(normalize-space(substring-after(//node,' ')),' ')),' '),1,1)"/>
</node1>
</xsl:template>
</xsl:stylesheet>
Please let me know if I can reduce the code in same xslt version 1.0
Upvotes: 1
Reputation: 461
<xsl:template match="node">
<xsl:variable name="s" select="tokenize(.,' ')"/>
<xsl:element name="node">
<xsl:for-each select="$s">
<xsl:value-of select="substring(.,1,1)"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
First of all tokenize the string then use substring for your desire output
Upvotes: 0
Reputation: 66781
Another option would be to use fn:replace()
with a regex and a capture group:
fn:replace("This Is W3 School", "([A-Z])\w+\s?", "$1")
Upvotes: 1
Reputation: 167716
You can easily use tokenize(., ' ')
in the context of the node
element to get a sequence of the strings, then you can use the substring
function for the first letter e.g. in XSLT 3 tokenize(., ' ')!substring(., 1, 1)
or in XSLT 2 for $token in tokenize(., ' ') return substring($token, 1, 1)
.
Then output the result with xsl:value-of
e.g. in XSLT 3
<xsl:template match="node">
<xsl:copy>
<xsl:value-of select="tokenize(., ' ')!substring(., 1, 1)" separator=""/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/6qVRKvY
or in XSLT 2 with
<xsl:template match="node">
<xsl:copy>
<xsl:value-of select="for $token in tokenize(., ' ') return substring($token, 1, 1)" separator=""/>
</xsl:copy>
</xsl:template>
Upvotes: 2