Subject: Re: [xsl] Math: Removing X number of zeroes from number Y. From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Tue, 7 Jun 2005 07:05:02 +1000 |
On 6/7/05, Ahsan Ali <doubleletter@xxxxxxxxx> wrote: > Hi, > > I have a fare element that is returned as, for example, 79000. The > decimal point value is specified in another element as for example 2. > Therefore the number should be: 790.00 > > There's a way to do this mathematically: > > Where x=DecimalPoint, and y=fare, the forumla would be y/(10^x) > > But as far as I know there's no exponential function in XSLT 1.0. I'm > using, or rather, _have_ to use MSXML, I can't go for FXSLT, etc. > > It's worth mentioning that fare is of type 'double' and DecimalPoint > is of type 'short' > > Anyone have any ideas on how to do this in plain XSL ? As a number of people have pointed out, this problem has a simple solution using the substring() function. This problem is a special case of a more general and very frequently encountered task: "Do something N times, every time using the result of the previous as input" This can be implemented on every case by manually coding a recursive template. Or it can be implemented once and forever, and then simply reused. This is the idea behind the "iter" template of FXSL. To use it one doesn't need to have the FXSL library -- the "iter" template has no dependencies on other FXSL templates. Here's the code for MSXML: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:vendor="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="xsl vendor"> <!-- =========================================================================== this implements functional power composition, that is f(f(...f(x)))))...) f composed with itself n - 1 times The corresponding Haskell code is: > iter :: (Ord a, Num a) => a -> (b -> b) -> b -> b > iter n f > | n > 0 = f . iter (n-1) f > | otherwise = id ===========================================================================-- > <!-- Template: iter Purpose: Iterate (compose a function with itself) N times Parameters:- $pTimes - [optional] number of times to iterate $pFun - a template reference to the function that's to be iterated $pX - an initial argument to the function ========================================================================== --> <xsl:template name="iter"> <xsl:param name="pTimes" select="0"/> <xsl:param name="pFun" select="/.."/> <xsl:param name="pX" /> <xsl:choose> <xsl:when test="$pTimes = 0" > <xsl:copy-of select="$pX"/> </xsl:when> <xsl:when test="$pTimes = 1"> <xsl:apply-templates select="$pFun"> <xsl:with-param name="arg1" select="$pX"/> </xsl:apply-templates> </xsl:when> <xsl:when test="$pTimes > 1"> <xsl:variable name="vHalfTimes" select="floor($pTimes div 2)"/> <xsl:variable name="vHalfIters"> <xsl:call-template name="iter"> <xsl:with-param name="pTimes" select="$vHalfTimes"/> <xsl:with-param name="pFun" select="$pFun"/> <xsl:with-param name="pX" select="$pX"/> </xsl:call-template> </xsl:variable> <xsl:call-template name="iter"> <xsl:with-param name="pTimes" select="$pTimes - $vHalfTimes"/> <xsl:with-param name="pFun" select="$pFun"/> <xsl:with-param name="pX" select="vendor:node-set($vHalfIters)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:message>[iter]Error: the $pTimes argument must be a positive integer or 0. </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> And here's an example how to use the iter template. This multiplies by 3 N times, where N = 4, and the result is, as expected, 81 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:myMultiplyby3="f:myMultiplyby3" exclude-result-prefixes="xsl myMultiplyby3"> <xsl:import href="iter.xsl"/> <xsl:output omit-xml-declaration="yes"/> <myMultiplyby3:myMultiplyby3/> <xsl:template match="/"> <xsl:variable name="vMultBy3" select="document('')/*/myMultiplyby3:*[1]"/> <xsl:call-template name="iter"> <xsl:with-param name="pTimes" select="4"/> <xsl:with-param name="pFun" select="$vMultBy3"/> <xsl:with-param name="pX" select="1"/> </xsl:call-template> </xsl:template> <xsl:template match="myMultiplyby3:*"> <xsl:param name="arg1"/> <xsl:value-of select="3 * $arg1"/> </xsl:template> </xsl:stylesheet> Cheers, Dimitre Novatchev.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Math: Removing X number of ze, Ahsan Ali | Thread | Re: [xsl] Math: Removing X number o, Mukul Gandhi |
[xsl] Works in firefox but not in i, Marzka, Jeremy | Date | [xsl] How to replace " with ', Jiang, Peiyun |
Month |