Reputation: 43
Hello Am a beginner to XSL hardly know few commands. I was trying out a sample where i have to format a number based on the entry in the XML. I want to use the format-number function to achieve the same.
<Details>
<Order>Bulk Order</Order>
<OrderDate>1997-07-16T19:20:30+01:00</OrderDate>
<Quantity>100</Quantity>
<Price>99.45</Price>
<Format>de_DE</Format>
</Details>
<Details>
<Order>Bulk Order</Order>
<OrderDate>1997-07-16T19:20:30+01:00</OrderDate>
<Quantity>100</Quantity>
<Price>99.45</Price>
<Format>en_US</Format>
</Details>
However i can render the output if i use :
<xsl:value-of select='format-number(500100, "###,###.00")' />
But i want to use a certain condition
i.e if the Format is de_DE : I want to pass the ###.###,00 to format-number method (note the decimal and thousand separators) or if the Format is en_US I want to pass the ###,###.00 to format-number method
I hopeless tried using choose statement ( but i really have no idea about the syntax of usage)
<xslt:choose>
<xslt:when test="$format = 'de_DE'">###,###.00</xslt:when>
<xslt:when test="$format = 'en_US'">###.###,00</xslt:when>
<xslt:otherwise>###.###,00</xslt:otherwise>
</xslt:choose>
Can anyone help me to put this onto a template or something so that i just call and i get the output based on the format present in the XML
Thanks Srivatsa
Upvotes: 4
Views: 173
Reputation: 243459
XSLT has the <xsl:decimal-format>
directive especially for this case.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:decimal-format name="de_DE" decimal-separator="." grouping-separator="," />
<xsl:decimal-format name="en_US" decimal-separator="," grouping-separator="."/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Price/text()">
<xsl:value-of select="format-number(., '#,###.##', ../../Format)"/>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document (wrapped into a top element node to be made well-formed):
<t>
<Details>
<Order>Bulk Order</Order>
<OrderDate>1997-07-16T19:20:30+01:00</OrderDate>
<Quantity>100</Quantity>
<Price>1199.45</Price>
<Format>de_DE</Format>
</Details>
<Details>
<Order>Bulk Order</Order>
<OrderDate>1997-07-16T19:20:30+01:00</OrderDate>
<Quantity>100</Quantity>
<Price>1199.45</Price>
<Format>en_US</Format>
</Details>
</t>
produces the wanted result:
<t>
<Details>
<Order>Bulk Order</Order>
<OrderDate>1997-07-16T19:20:30+01:00</OrderDate>
<Quantity>100</Quantity>
<Price>1,199.45</Price>
<Format>de_DE</Format>
</Details>
<Details>
<Order>Bulk Order</Order>
<OrderDate>1997-07-16T19:20:30+01:00</OrderDate>
<Quantity>100</Quantity>
<Price>1199,45</Price>
<Format>en_US</Format>
</Details>
</t>
Upvotes: 4
Reputation: 699
You could apply-templates and match on the value of the text node as follows:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="/root/Details"/>
</xsl:template>
<xsl:template match="Details">
<xsl:variable name="total" select="Price * Quantity"/>
<xsl:apply-templates select="Format">
<xsl:with-param name="total" select="$total"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Format[text()='de_DE']">
<xsl:param name="total"/>
<xsl:value-of select="format-number($total, '###.###.00')"/>
</xsl:template>
<xsl:template match="Format[text()='en_US']">
<xsl:param name="total"/>
<xsl:value-of select="format-number($total, '###,###.00')"/>
</xsl:template>
This code for example, matches all Details nodes and for each match gets the total for the order. It then does an apply-template on the format passing in the total as a parameter. The match then occurs on the value of the format node.
I think the format '###.###.00' is invalid as it seems that only one decimal point is allowed. '###,###.00' is fine.
Upvotes: 1
Reputation: 1140
Assuming you're in a template match for 'Details' nodes then you could do something like this:
<xslt:choose>
<xslt:when test="Format/text() = 'de_DE'"><xsl:value-of select="format-number(Price, '###,###.00')" /></xslt:when>
<xslt:when test="Format/text() = 'en_US'"><xsl:value-of select="format-number(Price, '###.###,00')" /></xslt:when>
<xslt:otherwise><xsl:value-of select='format-number(Price, "###.###,00")' /></xslt:otherwise>
</xslt:choose>
$format is for when you have a variable named 'format' defined by <xslt:variable/>. The test condition accepts XPath statements like Format (node child of Details) / text() (the text child node of Format)
Upvotes: 0