Jump to content

format-number respecting input's non-significant 0's


raptorw3s

Recommended Posts

Hi everybodyI've got a problem to solve, and I'm totally unfamiliar with XSLT :) This is my question: I receive currency values, and must format them in some given format, but respecting non-significant 0's. This is what I have in my hands now:string(format-number($someprice,'$#.##0,00', 'a_decimal_format'))Some inputs => outputs:0.1 => $0.101234567.89 => $1.234.567,89Now, this is the the problem: an input like 0001.6 will produce $1,60, but what I want is $0.001,60 (don't ask me why!). For the same reason, if the input is 04.49280, I want $04,49280 instead of $4,49.I hope I can get a generic solution, because my format can change, like '§#.#0,0000'How can I get this result I need?Any tip is greatly appreciated!Many thanks in advance!

Link to comment
Share on other sites

This ability is built into XSLTdefine a decimal format as in this example:<xsl:decimal-format name="myname" decimal-separator="," grouping-separator="."/>and use it as in this example: <xsl:template match="/"> <xsl:value-of select="format-number(1.60,'$0.000,00','myname')"/></xsl:template

Link to comment
Share on other sites

This ability is built into XSLTdefine a decimal format as in this example:<xsl:decimal-format name="myname" decimal-separator="," grouping-separator="."/>and use it as in this example: <xsl:template match="/"> <xsl:value-of select="format-number(1.60,'$0.000,00','myname')"/></xsl:template
Thanks, but you haven't got my problem.I have exactly what you posted (except that my format is '$#.##0,00'). It works fine, but does not respect non-significant zeros to the left/right, if present. I cannot insert extra 0's if they're not present (except for the basic ones - 0,00). I need a generic format that handles all cases.Examples of inputs/outputs that I need:1.6 => $1,602638.643 => $2.638,6431234567.89 => $1.234.567,8900001.9 => $00.001,9023.934000 => $23,9340000000037.3600000 => $0.000.037,3600000That IS weird, but that's what I need :) I was checking on what I can do with XSLT, and I'm afraid the only solution is to generate the format I need for every input. It sounds like a very dirty workaround, but I haven't found any other alternative. What I have in mind till now is:- use translate to turn all the input numers to 0's- split it into integer and decimal parts (with substring-after/before)- integer part: make sure it contains at least one 0, and if it contains at least 4 characters, insert a '.' in the 4th position from the right (still have to figure out how to do this)- decimal part: make sure it contains at least two 0- concat the two parts again, with a ',' between themSounds bad, doesn't it?If anyone can point out a better solution, I really appreciate!Thanks again!
Link to comment
Share on other sites

I feel bad about not reading your question more thoroughly. The following code will dynamically create a mask for each value. Sorry for the quick reply beforeThis was the XML

<nums>	<num>1.6</num>	<num>2638.643</num>	<num>1234567.89</num>	<num>00001.9</num>	<num>23.934000</num>	<num>0000037.3600000</num></nums>

And the XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >	<xsl:output method="html"/>	<xsl:decimal-format name="myname" decimal-separator="," grouping-separator="."/>	<xsl:variable name="numbers">123456789></xsl:variable>	<xsl:variable name="zeros">000000000</xsl:variable>		<xsl:template match="/" >		<xsl:for-each select="//num">			<xsl:variable name="trailing" select="substring-after(.,'.')" />						<xsl:variable name="trailingmask">				<xsl:choose>					<xsl:when test="string-length($trailing) <= 2">						<xsl:text>,00</xsl:text>					</xsl:when>					<xsl:otherwise>						<xsl:value-of select="concat(',',translate($trailing,$numbers,$zeros))"/>					</xsl:otherwise>				</xsl:choose>			</xsl:variable>						<xsl:variable name="leadingmask">				<xsl:call-template name="setmask">					<xsl:with-param name="count" select="1" />					<xsl:with-param name="length" select="string-length(substring-before(.,'.'))" />				</xsl:call-template>			</xsl:variable>					<xsl:value-of select="format-number(.,concat('$',$leadingmask,$trailingmask),'myname')"/>			<hr/>		</xsl:for-each>	</xsl:template>	<xsl:template name="setmask">		<xsl:param name="count" />		<xsl:param name="length" />		<xsl:text>0</xsl:text>		<xsl:if test="($length - $count) mod 3 = 0 and $count != $length">.</xsl:if>		<xsl:if test="$count < $length">			<xsl:call-template name="setmask">				<xsl:with-param name="count" select="$count + 1"/>				<xsl:with-param name="length" select="$length" />			</xsl:call-template>		</xsl:if>	</xsl:template></xsl:stylesheet>

The result:

$1,60--------------------------------------------------------------------------------$2.638,643--------------------------------------------------------------------------------$1.234.567,89--------------------------------------------------------------------------------$00.001,90--------------------------------------------------------------------------------$23,934000--------------------------------------------------------------------------------$0.000.037,3600000--------------------------------------------------------------------------------

Link to comment
Share on other sites

Oh my! I never expected someone posting a full solution!Many many thanks, aalbetski!It helped me a lot! I could adapt it to my macros and it's working nicely! :)And... just wondering, this approach is really the only one for this issue?I mean, there's no way to avoid building my own masks per input, right?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...