本文介绍了XSLT 1.0 中的数字舍入和精度问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 xsl 时出现不一致,

I have an inconsistency while using xsl,

这里是xml,

<Rate>
    <TotalRate>506.41</TotalRate>
    <TotalTax>17</TotalTax>
    <Currency>INR</Currency>
</Rate>

和 xsl,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <TotalAmount>
            <xsl:value-of select="Rate/TotalRate + Rate/TotalTax"/>
        </TotalAmount>
    </xsl:template>
</xsl:stylesheet>

输出是,

<TotalAmount xmlns:fo="http://www.w3.org/1999/XSL/Format">523.4100000000001</TotalAmount>

但预期的 o/p 是,

but the expected o/p is,

<TotalAmount xmlns:fo="http://www.w3.org/1999/XSL/Format">523.41</TotalAmount>

为什么 o/p 是 523.4100000000001?如何在不四舍五入的情况下获得 523.41?

Why the o/p is 523.4100000000001? how can i get 523.41 without rounding it?

推荐答案

在 XSLT 1.0 中,数字使用 double 类型 和任何二进制浮点类型实现,存在精度损失.

In XSLT 1.0 numbers are implemented with the double type and as with any binary floating-point type, there is a loss of precision.

在 XSLT 2.0/XPath 2.0 中,可以使用 xs:decimal 类型在不损失精度的情况下工作.

In XSLT 2.0/XPath 2.0 one can use the xs:decimal type to work without loss of precision.

我.XSLT 1.0 解决方案:

使用格式-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:

<TotalAmount>523.41</TotalAmount>
<TotalAmount>523.4100000000001</TotalAmount>

二.使用 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>

这篇关于XSLT 1.0 中的数字舍入和精度问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-15 21:22