我正在使用Apache FOP 2.3从xml和xslt文件创建pdf。
我有以下XML:
<root>
<operations>
<operation>
<sold>5800.00</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>422.92</sold>
</operation>
<operation>
<sold>0.00</sold>
</operation>
</operations>
</root>
在xslt文件中,我有以下一行:
<xsl:value-of select="sum(.//operation/sold[number(.) = .])"/>
这将计算所有sold
元素的总和,得出11297.960000000001
(正确的结果将是11297.96
)。我需要将其四舍五入为两位小数,例如:11297.96
。另外,如果第二个小数为0,我仍要显示它,所以如果总和为12.3
,我希望显示12.30
。
答案 0 :(得分:0)
根据XSLT版本和处理器,您可以通过对XSLT / XPath 2或更高版本sum(.//operation/sold/xs:decimal(.))
中的小数求和来避免双重误差,根据需要格式化任何数字,可以使用format-number
,例如format-number(sum(.//operation/sold/xs:decimal(.)), '0.00')
。
xs:decimal
数据类型比xs:double
(在XPath 1中分别为数字)数据类型提供更高的精度,您看到的不准确之处就是IEEE如何定义IEEE双精度64- XSLT / XPath 2和更高版本从XSD模式语言https://www.w3.org/TR/xmlschema-2/#double继承的位浮点类型。在使用该数据类型的其他编程语言中,您会发现同样的问题(例如Javascript http://jsfiddle.net/23g5wexz/)。
sum(.//operation/sold)
将与xs:double
数据类型(https://www.w3.org/TR/xpath-functions/#func-sum)一起使用,如果您知道无论如何都对结果使用format-number
,则足以与默认{ {1}(我认为默认值主要用于XSLT / XPath 2和更高版本,以便与XSLT / XPath向后兼容,因为XSLT / XPath存在实现/遵循IEEE双精度64位浮点规范的单个数字数据类型。)