Hide
Siafoo is here to make coding less frustrating and to save you time. Join Siafoo Now or Learn More

XSL Transform for converting from scientific notation to decimal number Atom Feed 0

In Brief This converts scientific notation to a string of numbers.... more
# 's
  1<xsl:stylesheet
2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
3 version="1.0"
4>
5
6<xsl:output method="xml"/>
7<!--
8 ConvertSciToNumString
9 By: Michael Case
10 University of California, Davis
11 case@xxxxxxxxxxxxxxxxxx
12
13
14 Converts a string from Scientific notation to an XML acceptable number
15(as a string).
16 e.g. convert from 1E-10 to 0.0000000001
17
18 Include this template in your XSL file using: <xsl:include
19href="ConvertSciToNumString.xsl">
20
21 Input parameters to ConvertSciToNumString
22 myval the number to be checked.
23
24 Input parameters to realConvertSciToNumString (base 10 assumed):
25 vnum the un-signed mantissa
26 sgn the sign, an empty string or '-'
27
28 This puts out a text result which can be enclosed in the calling XSL
29with <xsl:element>,
30 <xsl:attribute> or nothing (leave as text).
31
32-->
33
34<!-- necessary global maximum/minimum of exponent 'stuffer', set to 100
35-->
36<xsl:variable name="max-exp">
37 <xsl:value-of
38select="'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'"/>
39</xsl:variable>
40
41<xsl:template name="convertSciToNumString">
42 <xsl:param name="myval" select="''"/>
43 <xsl:variable name="useval">
44 <xsl:value-of select="translate(string($myval),'e','E')"/>
45 </xsl:variable>
46
47 <xsl:choose>
48 <xsl:when test="not(number($useval))">
49 <xsl:choose>
50 <xsl:when test="number(substring-before($useval, 'E'))">
51
52 <xsl:choose>
53 <xsl:when test="number(substring-after($useval, 'E'))">
54 <xsl:if test="number(substring-before($useval, 'E')) &lt;
550">
56 <xsl:call-template name="realConvertSciToNumString">
57 <xsl:with-param name="vnum"
58select="substring-after($useval, '-')"/>
59 <xsl:with-param name="vsgn" select="'-'"/>
60 </xsl:call-template>
61 </xsl:if>
62 <xsl:if test="number(substring-before($useval, 'E')) &gt;
630">
64 <xsl:call-template name="realConvertSciToNumString">
65 <xsl:with-param name="vnum" select="$useval"/>
66 </xsl:call-template>
67 </xsl:if>
68 </xsl:when>
69
70 <xsl:otherwise>
71 <xsl:value-of select="$useval"/>
72 </xsl:otherwise>
73
74 </xsl:choose>
75 </xsl:when>
76
77 <xsl:otherwise>
78 <xsl:value-of select="$useval"/>
79 </xsl:otherwise>
80
81 </xsl:choose>
82 </xsl:when>
83
84 <xsl:otherwise>
85 <xsl:value-of select="number($useval)"/>
86 </xsl:otherwise>
87
88 </xsl:choose>
89</xsl:template>
90
91<xsl:template name="realConvertSciToNumString" >
92 <xsl:param name="vnum" select="0"/>
93 <xsl:param name="vsgn" select="''"/>
94 <xsl:choose>
95 <xsl:when test="number(vnum)">
96 <xsl:value-of select="$vnum"/>
97 </xsl:when>
98 <xsl:otherwise>
99 <xsl:variable name="vmantisa">
100 <xsl:value-of select="number(substring-before($vnum,
101'E'))"/>
102 </xsl:variable>
103 <xsl:variable name="vexponent">
104 <xsl:value-of select="number(substring-after($vnum,
105'E'))"/>
106 </xsl:variable>
107
108 <!-- handle 0.9.... -->
109 <xsl:if test="$vmantisa &lt; 1">
110
111 <!-- handle 0.9E-9 -->
112 <xsl:if test="$vexponent &lt; 0">
113 <xsl:variable name="voffset">
114 <xsl:value-of
115select="string-length(substring-before($vmantisa, '.'))"/>
116 </xsl:variable>
117 <xsl:value-of select="concat($vsgn, '0', '.',
118substring($max-exp, 1, ($vexponent * -1) -
119$voffset),substring-before($vmantisa,'.'), substring-after($vmantisa,
120'.'))"/>
121 </xsl:if>
122
123 <!-- handle 0.9E9 -->
124 <xsl:if test="$vexponent &gt; 0">
125 <xsl:variable name="voffset">
126 <xsl:value-of
127select="string-length(substring-after($vmantisa, '.'))"/>
128 </xsl:variable>
129
130 <xsl:choose>
131 <!-- handle .932E1 -->
132 <xsl:when test="$voffset &gt; $vexponent">
133 <xsl:value-of select="concat($vsgn,
134substring(substring-after($vmantisa, '.'), 1, $vexponent), '.',
135substring(substring-after($vmantisa, '.'), $vexponent + 1,
136string-length($vmantisa) - $vexponent))"/>
137 </xsl:when>
138
139 <!-- handle .9E3 -->
140 <xsl:when test="$voffset &lt; $vexponent">
141 <xsl:value-of select="concat($vsgn,
142substring-after($vmantisa, '.'), substring($max-exp, 1, ($vexponent -
143$voffset)))"/>
144 </xsl:when>
145
146 <!-- handle .9E1 -->
147 <xsl:when test="$voffset = $vexponent">
148 <xsl:value-of select="concat($vsgn,
149substring-before($vmantisa, '.'), substring-after($vmantisa, '.'))"/>
150 </xsl:when>
151
152 <xsl:otherwise>
153 <xsl:value-of select="NaN"/>
154 </xsl:otherwise>
155
156 </xsl:choose>
157
158 </xsl:if>
159 </xsl:if>
160
161 <!-- handle 9.9.... -->
162 <xsl:if test="$vmantisa &gt;= 1">
163
164 <!-- handle 9.9E-9 -->
165 <xsl:if test="$vexponent &lt; 0">
166 <xsl:variable name="voffset">
167 <xsl:value-of
168select="string-length(substring-before($vmantisa, '.'))"/>
169 </xsl:variable>
170
171 <xsl:choose>
172
173 <!-- really handle 923.9E-1 -->
174 <xsl:when test="$voffset &gt; $vexponent * -1">
175 <xsl:value-of select="concat($vsgn,
176substring(substring-before($vmantisa, '.'), 1,
177string-length(substring-before($vmantisa, '.')) + $vexponent), '.',
178substring(substring-before($vmantisa, '.'),
179string-length(substring-before($vmantisa, '.')) + $vexponent + 1,
180$vexponent * -1), substring-after($vmantisa, '.'))"/>
181 </xsl:when>
182
183 <!-- really handle 9.9E-9 -->
184 <xsl:when test="$voffset &lt; $vexponent * -1 and
185$voffset &gt; 0">
186 <xsl:value-of select="concat($vsgn, '0', '.',
187substring($max-exp, 1, ($vexponent * -1) - $voffset),
188substring-before($vmantisa, '.'), substring-after($vmantisa, '.'))"/>
189 </xsl:when>
190
191 <!-- handle 9.9E-1 -->
192 <xsl:when test="$voffset = $vexponent * -1 and
193$voffset &gt; 0">
194 <xsl:value-of select="concat($vsgn, '0', '.',
195substring-before($vmantisa, '.'), substring-after($vmantisa, '.'))"/>
196 </xsl:when>
197
198 <!-- handle 9E-9 -->
199 <xsl:when test="$voffset = 0 and
200string-length($vmantisa) &lt; $vexponent * -1">
201 <xsl:value-of select="concat($vsgn, '0', '.',
202substring($max-exp, 1, ($vexponent * -1) - string-length($vmantisa)),
203$vmantisa)"/>
204 </xsl:when>
205
206 <!-- handle 999E-1-->
207 <xsl:when test="$voffset = 0 and
208string-length($vmantisa) &gt; $vexponent * -1">
209 <xsl:value-of select="concat($vsgn,
210substring($vmantisa, 1, string-length($vmantisa) + $vexponent), '.',
211substring($vmantisa, string-length($vmantisa) + $vexponent + 1,
212$vexponent * -1))"/>
213 </xsl:when>
214
215 <xsl:otherwise>
216 <xsl:value-of select="'NaN'"/>
217 </xsl:otherwise>
218
219 </xsl:choose>
220
221 </xsl:if>
222
223 <!-- handle 9.9E9 -->
224 <xsl:if test="$vexponent &gt; 0">
225 <xsl:variable name="voffset">
226 <xsl:value-of
227select="string-length(substring-after($vmantisa, '.'))"/>
228 </xsl:variable>
229 <xsl:value-of select="concat($vsgn,
230substring-before($vmantisa, '.'), substring-after($vmantisa, '.'),
231substring($max-exp, 1, ($vexponent - 1 - $voffset)))"/>
232 </xsl:if>
233 </xsl:if>
234 </xsl:otherwise>
235 </xsl:choose>
236</xsl:template>
237
238</xsl:stylesheet>

This converts scientific notation to a string of numbers.

An example of how to use the transform:

# 's
 1<xsl:stylesheet
2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
3 version="1.0"
4>
5<!--
6 Example usage of ConvertSciToNumString.xsl
7-->
8
9<xsl:template match="/">
10 <html>
11 <head>
12 <title>Output for web page</title>
13 </head>
14 <body>
15 <xsl:apply-templates/>
16 </body>
17 </html>
18</xsl:template>
19
20<xsl:template match="main">
21 <table border="1" align="center">
22 <th>num</th>
23 <th>converted</th>
24 <th>number()</th>
25 <xsl:apply-templates/>
26 </table>
27</xsl:template>
28
29<xsl:template match="mynum">
30 <tr>
31 <td><xsl:value-of select="@num"/></td>
32 <td>
33 <xsl:call-template name="convertSciToNumString">
34 <xsl:with-param name="myval" select="@num"/>
35 </xsl:call-template>
36 </td>
37 <td><xsl:value-of select="number(@num)"/></td>
38 </tr>
39</xsl:template>
40
41<xsl:include href="ConvertSciToNumString.xsl"/>
42
43</xsl:stylesheet>

And a test case for verifying correctness of the transform.

# 's
 1<main>
2 <mynum num="1"/>
3 <mynum num="-2"/>
4 <mynum num="3E-3"/>
5 <mynum num="-2E-4"/>
6 <mynum num=".5E-3"/>
7 <mynum num=".3E4"/>
8 <mynum num=".2E-4"/>
9 <mynum num="-.6E3"/>
10 <mynum num="-.6E-4"/>
11 <mynum num="6.022E23"/>
12 <mynum num=".312E1"/>
13 <mynum num="312E-2"/>
14 <mynum num="-0.312E1"/>
15 <mynum num="-312E-2"/>
16 <mynum num="923.9E-1"/>
17 <mynum num="1.625E-12"/>
18 <mynum num="1.E-5"/>
19 <mynum num="2.14160E-3"/>
20 <mynum num="2.14160e-3"/>
21</main>

Comments

over 8 years ago (20 Apr 2010 at 08:26 AM) by ludek.vodicka
Here is another implementation for conversion scientific numbers to decimal.
Original "convertSciToNumString" from Michael Case mentioned here have some bugs while working with positive exponents.

http://www.orm-designer.com/article/xslt-convert-scientific-notation-to-decimal-number