0

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.

5 Answers 5

2

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>
Sign up to request clarification or add additional context in comments.

Comments

1

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

1 Comment

Please see my answer below for an XSLT 1.0 alternative that can handle more than one node element in the document and also handles more than 5 substrings.
1

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")

Comments

1

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

Comments

0
<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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.