-1

I am very much new to XSLT and have a weird requirement for which I have not found any solution. Server side we have XSLT of version 2.0.

Input number can be from Zero (0) to any value up to 8-digit number. I need to convert this into its English Word-Meaning following specific format.

If number is of 5 digit (Example - 28651) then First three set will be of 5-Astric (*****) followed by 2-space, so total 7.

If English word of any digit contains less than 5 letter (example 6 SIX then it must be followed by 2+2=4 spaces to make it equivalent to 5 letter English WORD)

For the Last digit of the number must also followed by 2 spaces as above.

   INPUT       OUTPUT (Without Enclosing Double-Quote)

    9375 = "*****  *****  *****  *****  NINE   THREE  SEVEN  FIVE   "
    8623 = "*****  *****  *****  *****  EIGHT  SIX    TWO    THREE  "
       0 = "*****  *****  *****  *****  *****  *****  *****  ZERO   "
   28651 = "*****  *****  *****  TWO    EIGHT  SIX    FIVE   ONE    "

40378623 = "FOUR   ZERO   THREE  SEVEN  EIGHT  SIX    TWO    THREE  "

I am not able to perform any below operation which is quite easy with Java.

1.) Assign any value to existing variable back. 2.) Taking the reverse of the number (345 to 543) 3.) Fetch out each digit separately in any array or something.

This is what I was thinking for its approach.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 1
    Asking for help with an assignment is fine, provided you've shown what you've tried and specifically where you're stuck -- don't just post the specification and hope someone will do it for you. – kjhughes Jul 06 '17 at 12:34
  • 1
    Regarding the approach you list, you should instead think more functionally than procedurally. See, for example, [*How to change or reassign a variable in XSLT?*](https://stackoverflow.com/q/19255139/290085) – kjhughes Jul 06 '17 at 13:41
  • Thanks @kjhughes for your reply. Yes you are correct i should have prepare something in advance to ask for any particular doubt but I was not having anything ready by that. But after your motivation I wrote something like this below to achieve my requirement which is very basic way of coding as i am novice to its syntax. – Pawan Sarswat Jul 06 '17 at 19:22

2 Answers2

4

This is actually not very difficult to do in XSLT 2.0. Consider the following example:

XML

<input>
    <entry>0</entry>
    <entry>12</entry>
    <entry>345</entry>
    <entry>6789</entry>
    <entry>24680</entry>
    <entry>135797</entry>
    <entry>1234567</entry>
    <entry>87654321</entry>
</input>

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />

<xsl:variable name="strings" select="('ZERO   ', 'ONE    ', 'TWO    ', 'THREE  ', 'FOUR   ', 'FIVE   ', 'SIX    ', 'SEVEN  ', 'EIGHT  ', 'NINE   ')" />

<xsl:template match="/input">
    <xsl:for-each select="entry">
        <!-- padding -->
        <xsl:for-each select="1 to 8 - string-length(.)">
            <xsl:text>*****  </xsl:text>
        </xsl:for-each>
        <!-- digits to strings   -->
        <xsl:for-each select="string-to-codepoints(.)">
            <xsl:variable name="i" select="codepoints-to-string(.) " /> 
            <xsl:value-of select="$strings[number($i) + 1]"/>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Result

*****  *****  *****  *****  *****  *****  *****  ZERO   
*****  *****  *****  *****  *****  *****  ONE    TWO    
*****  *****  *****  *****  *****  THREE  FOUR   FIVE   
*****  *****  *****  *****  SIX    SEVEN  EIGHT  NINE   
*****  *****  *****  TWO    FOUR   SIX    EIGHT  ZERO   
*****  *****  ONE    THREE  FIVE   SEVEN  NINE   SEVEN  
*****  ONE    TWO    THREE  FOUR   FIVE   SIX    SEVEN  
EIGHT  SEVEN  SIX    FIVE   FOUR   THREE  TWO    ONE    
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Thanks a lot for your fruitful effort, this is exactly what I was looking for. I was not aware with all these standard library functions and syntax to make the best code with its complexity-level. Thanks again for letting me think into a different direction. Below is my code to achieve that but that is not a best practice of coding. – Pawan Sarswat Jul 06 '17 at 19:37
0

I wrote something like this below to achieve my requirement which is very basic way of coding as i am novice to its syntax. But this is working in a way what I need for. I agree this is not a good practice of coding.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:template name="digits">

        <xsl:param name="text" />

        <xsl:if test="$text != ''">

          <xsl:variable name="letter" select="substring($text, 1, 1)" />

          <xsl:if test="$letter = '0'">
           <xsl:text>ZERO   </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '1'">
           <xsl:text>ONE    </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '2'">
           <xsl:text>TWO    </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '3'">
           <xsl:text>THREE  </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '4'">
           <xsl:text>FOUR   </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '5'">
           <xsl:text>FIVE   </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '6'">
           <xsl:text>SIX    </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '7'">
           <xsl:text>SEVEN  </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '8'">
           <xsl:text>EIGHT  </xsl:text>
          </xsl:if>
          <xsl:if test="$letter = '9'">
           <xsl:text>NINE   </xsl:text>
          </xsl:if>

          <xsl:call-template name="digits">
            <xsl:with-param name="text" select="substring-after($text, $letter)" />
          </xsl:call-template>

        </xsl:if>

      </xsl:template>

      <xsl:template match="/">
          <xsl:variable name="Vnum">
             <xsl:number value="/Payment/Amount"/>
          </xsl:variable>
          <xsl:variable name="Vlen">
            <xsl:value-of select="string-length($Vnum)" />
          </xsl:variable>

                    <xsl:if test="$Vlen = '1'">
                        <xsl:text>*****  *****  *****  *****  *****  *****  *****  </xsl:text>
                    </xsl:if>
                    <xsl:if test="$Vlen = '2'">
                        <xsl:text>*****  *****  *****  *****  *****  *****  </xsl:text>
                    </xsl:if>
                    <xsl:if test="$Vlen = '3'">
                        <xsl:text>*****  *****  *****  *****  *****  </xsl:text>
                    </xsl:if>
                    <xsl:if test="$Vlen = '4'">
                        <xsl:text>*****  *****  *****  *****  </xsl:text>
                    </xsl:if>
                    <xsl:if test="$Vlen = '5'">
                        <xsl:text>*****  *****  *****  </xsl:text>
                    </xsl:if>
                    <xsl:if test="$Vlen = '6'">
                        <xsl:text>*****  *****  </xsl:text>
                    </xsl:if>
                    <xsl:if test="$Vlen = '7'">
                        <xsl:text>*****  </xsl:text>
                    </xsl:if>

          <xsl:call-template name="digits">
            <xsl:with-param name="text" select="$Vnum"/>
          </xsl:call-template>
      </xsl:template>
    </xsl:stylesheet>