cancel
Showing results for 
Search instead for 
Did you mean: 

Need Help on XSLT Code

maheswarareddykonda
Active Contributor
0 Kudos

Hi Experts,

I am working existed interface which had developed on XSLT code.

here i need to edit few changes, can anyone please help.

here is the requirement.

Input:

<ABC>.123.345.567.789</ABC>

Output:

<A>

  <xyz>.123</xyz>

</A>

<A>

  <xyz>.123.345</xyz>

</A>

<A>

  <xyz>.123.345.567</xyz>

</A>

<A>

  <xyz>.123.345.567.789</xyz>

</A>

Thanks in Advance.

Thanks & Regards,

Maheswarareddy

Accepted Solutions (1)

Accepted Solutions (1)

former_member190293
Active Contributor
0 Kudos

Hi Maheswarareddy Konda!

You can try something like this:

<?xml version='1.0'?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

    

     <Root>

          <xsl:apply-templates select="//String"/>

     </Root>

</xsl:template>

<xsl:template match="String">

     <xsl:call-template name="Split">

          <xsl:with-param name="srcStr" select="''"/>

          <xsl:with-param name="sep" select="''"/>

          <xsl:with-param name="restStr" select="text()"/>

     </xsl:call-template>

</xsl:template>

<xsl:template name="Split">

     <xsl:param name="srcStr"/>

     <xsl:param name="sep"/>

     <xsl:param name="restStr"/>

     <xsl:if test="string-length($restStr)">

          <xsl:variable name="token">

               <xsl:choose>

                    <xsl:when test="contains($restStr, '.')">

                         <xsl:value-of select="substring-before($restStr, '.')" />

                    </xsl:when>

                    <xsl:otherwise>

                         <xsl:value-of select="$restStr" />

                    </xsl:otherwise>

               </xsl:choose>

          </xsl:variable>

          <xsl:variable name="currText" select="concat($srcStr, concat($sep, $token))" />

          <item>

               <text> <xsl:value-of select="$currText"/> </text>

          </item>

          <xsl:call-template name="Split">

               <xsl:with-param name="srcStr" select="$currText" />

               <xsl:with-param name="sep" select="'.'" />

               <xsl:with-param name="restStr" select="substring-after($restStr, '.')" />

          </xsl:call-template>

     </xsl:if>

</xsl:template>

</xsl:stylesheet>

For source XML:

<?xml version="1.0" encoding="UTF-8"?>

<ns0:MyMessage xmlns:ns0="urn://test">

     <String>111.222.333.444.555</String>

</ns0:MyMessage>

Result is:

<?xml version='1.0' ?>

<Root>

     <item>

          <text>111</text>

     </item>

     <item>

          <text>111.222</text>

     </item>

     <item>

          <text>111.222.333</text>

     </item>

     <item>

          <text>111.222.333.444</text>

     </item>

     <item>

          <text>111.222.333.444.555</text>

     </item>

</Root>

Probably It's not optimized as I wrote this transformation very quickly. You can modify it accordingly. The main idea is to use recursive template call.

Regards.

former_member190293
Active Contributor
0 Kudos

For string with leading dot just change the code:


<?xml version='1.0'?>

<xsl:stylesheet version="1.0"

  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

  xmlns:ns0="urn://test">

<xsl:template match="ns0:MyMessage">

   <Root>

       <xsl:apply-templates select="String"/>

  </Root>

</xsl:template>

<xsl:template name="SplitString" match="String">

      <xsl:param name="startStr" select="''"/>

      <xsl:param name="delimeter" select="'.'"/>

      <xsl:param name="restStr" select="substring-after(text(), '.')"/>

     <xsl:if test="string-length($restStr)">

          <xsl:variable name="token">

               <xsl:choose>

                    <xsl:when test="contains($restStr, '.')"> <xsl:value-of select="substring-before($restStr, '.')" /> </xsl:when>

                    <xsl:otherwise> <xsl:value-of select="$restStr" /> </xsl:otherwise>

               </xsl:choose>

          </xsl:variable>

          <xsl:variable name="currText" select="concat($startStr, concat($delimeter, $token))" />

          <item>

               <text> <xsl:value-of select="$currText"/> </text>

          </item>

          <xsl:call-template name="SplitString">

               <xsl:with-param name="startStr" select="$currText" />

               <xsl:with-param name="delimeter" select="'.'" />

               <xsl:with-param name="restStr" select="substring-after($restStr, '.')" />

          </xsl:call-template>

     </xsl:if>

</xsl:template>

</xsl:stylesheet>

maheswarareddykonda
Active Contributor
0 Kudos

Hi Evgeniy,

Thanks for your reply, seems almost fit for me..

i will test and let you know

thanks again

Answers (2)

Answers (2)

iaki_vila
Active Contributor
0 Kudos

Hi Maheswarareddy Konda,

With XSLT seems to be a bit difficult, i would recommend to use java code in a UDF or java mapping. I tried it with XSLT but i haven't enough time to help you better. The main problem with XSLT is that you will need to do a reverse substring, starting with the end of the string.

A good way to start is this thread:

http://stackoverflow.com/questions/11166784/xslt-1-0-finding-the-last-occurence-and-taking-string-be...

And to know how use the string functions FunctX XSLT Functions: Strings

Regards.

maheswarareddykonda
Active Contributor
0 Kudos

Any thoughts please

nitindeshpande
Active Contributor
0 Kudos

Hi Maheshwar,

The input length would be fixed? Then you can easily read it as string in XSLT mapping and use the sub-string functionality to put the data.

Regards,

Nitin

maheswarareddykonda
Active Contributor
0 Kudos

Hi Nitin,

its not fixed length