带舍入的XSLT数字格式显示负零

时间:2014-07-30 08:58:39

标签: xml xslt saxon

在格式化需要舍入的小负数时,有没有办法阻止XSLT显示负零值?

以下代码

<xsl:variable name="myNum" select="-0.0001"/>
MyNum = <xsl:value-of select="$myNum"/>
MyNumrounded = <xsl:value-of select="format-number($myNum, '0.0%')"/>

将生成以下结果

MyNum = -0.0001
MyNumrounded = -0.0%

理想情况下会显示

MyNum = -0.0001
MyNumrounded = 0.0%

我目前正在使用Saxon HE 9.5.0.1

完整的测试XSLT是:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="*">
        <test>
            <xsl:variable name="myNum" select="-0.0001"/>
            MyNum = <xsl:value-of select="$myNum"/>
            MyNumrounded = <xsl:value-of select="format-number($myNum, '0.0%')"/>
        </test>
    </xsl:template>
</xsl:stylesheet>

此致

标记

3 个答案:

答案 0 :(得分:1)

format-number实际上并没有围绕一个数字,它只是格式化它。 要对数字进行舍入,您可以使用round()ceiling()floor(),具体取决于您要执行的操作。

这样做:

<xsl:variable name="myNum" select="-0.0001"/>
MyNum = <xsl:value-of select="$myNum"/>
MyNumrounded = <xsl:value-of select="format-number(round($myNum), '0.0%')"/>

会导致:

MyNum = -0.0001
MyNumrounded = 0.0%

但请注意,round总是舍入为整数,因此0.1也会导致0.0%。 要舍入到某个数字,您必须编写自己的函数。 所以,以防万一,因为您使用的是Saxon 9.5,您可以使用XSLT 2.0,所以这里有一组函数可用于舍入到小数位:

<xsl:function name="f:pow">
    <xsl:param name="base" as="xs:integer"/>
    <xsl:param name="exp" as="xs:integer"/>
    <xsl:choose>
        <xsl:when test="$exp eq 1">
            <xsl:value-of select="$base"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$base * f:pow($base, $exp - 1)"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:function>

<xsl:function name="f:roundToDecimal">
    <xsl:param name="input"/>
    <xsl:param name="dec" as="xs:integer"/>
    <xsl:variable name="mult" select="f:pow(10,$dec)"/>
    <xsl:if test="$input castable as xs:double">
        <xsl:value-of select="round($input * $mult) div $mult"/>
    </xsl:if>
</xsl:function>

所以基本上将你的数字乘以10的幂,舍入,除以10的相同幂。

答案 1 :(得分:0)

您需要实际围绕数字 - 而不仅仅是格式化:

<xsl:value-of select="format-number(round($myNum), '0.0%')"/>

或者,因为你想要四舍五入到百分之十:

<xsl:value-of select="format-number(round($myNum * 1000) div 1000, '0.0%')"/> 

但请注意,round() function的规范指出:

  

如果参数小于零,但大于或等于-0.5,   然后返回负零。

但我相信这只在Saxon 6.5中实现。

答案 2 :(得分:0)

我怀疑你在样式表中使用XPath 1.0模式,因此-0.0001被视为xs:double而不是xs:decimal。最简单的解决方案可能是切换到XPath 2.0模式(设置版本=&#34; 2.0&#34;),这将在十进制算术中完成。 xs:decimal数据类型没有负零。