Hide
Stay up to dateembedded code automagically updates, each snippet and article has a feed 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 6 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