XSLT 1.0 では、数値はdouble型で実装されており、他のバイナリ浮動小数点型と同様に、精度が失われます。
XSLT 2.0/XPath 2.0 では、xs:decimal
型を使用して精度を損なうことなく動作させることができます。
I. XSLT 1.0 ソリューション:
format-number()
関数を使用します。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<TotalAmount>
<xsl:value-of select="format-number(TotalRate + TotalTax, '0.##')"/>
</TotalAmount>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<Rate>
<TotalRate>506.41</TotalRate>
<TotalTax>17</TotalTax>
<Currency>INR</Currency>
</Rate>
必要な正しい結果が生成されます。
<TotalAmount>523.41</TotalAmount>
また、必要な精度が静的に認識されず、外部/グローバル パラメータとして変換に渡される可能性があることを示す例も示します。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pPrec" select="2"/>
<xsl:param name="pPrec2" select="13"/>
<xsl:variable name="vPict" select="'##################'"/>
<xsl:template match="/*">
<TotalAmount>
<xsl:value-of select=
"format-number(TotalRate + TotalTax,
concat('0.', substring($vPict,1,$pPrec))
)"/>
</TotalAmount>
<TotalAmount>
<xsl:value-of select=
"format-number(TotalRate + TotalTax,
concat('0.', substring($vPict,1,$pPrec2))
)"/>
</TotalAmount>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、精度 2 と精度 13 の 2 つの結果が生成されます。
<TotalAmount>523.41</TotalAmount>
<TotalAmount>523.4100000000001</TotalAmount>
Ⅱ.を使用した XSLT 2.0 ソリューションxs:decimal
:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<TotalAmount>
<xsl:value-of select="xs:decimal(TotalRate) + xs:decimal(TotalTax)"/>
</TotalAmount>
</xsl:template>
</xsl:stylesheet>
この変換が同じ XML ドキュメント (上記) に適用されると、必要な正しい結果が生成されます。
<TotalAmount>523.41</TotalAmount>