XSLT中format-number按输入小数位保留尾随零的实现问题
XSLT format-number 保留原始小数位数问题解答
核心结论
仅靠format-number的picture格式串无法实现你要的效果。format-number的处理对象是数值,当你把@value属性传入函数时,XSLT会先将字符串类型的属性值转为数值,而数值层面02.2和02.20是完全相等的,不存在任何差异,格式串不可能区分二者输出不同的尾随零。
问题复现
输入XML
<testvalues> <test value="02.25"/> <test value="02.2"/> <test value="02.20"/> </testvalues>
期望输出
<testvalues> <test>02.25</test> <test>02.2</test> <test>02.20</test> </testvalues>
测试格式串的实际问题
你测试的三个格式串都只能基于数值本身做格式化,无法识别原始字符串的小数位数:
00.00:强制保留2位小数,02.2会被输出为02.2000.0:强制截断为1位小数,02.25会被输出为02.200.0#:第二位为可选位,仅当非0时显示,02.20会被输出为02.2
实现方案
需要先读取原始属性的字符串值,判断小数点后的位数,再选择对应的格式化规则,XSLT 2.0实现代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="testvalues"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="test"> <xsl:copy> <xsl:variable name="rawValue" select="@value"/> <xsl:variable name="decimalPart" select="substring-after($rawValue, '.')"/> <xsl:choose> <!-- 小数部分长度≤1时,按1位小数格式化 --> <xsl:when test="string-length($decimalPart) le 1"> <xsl:value-of select="format-number($rawValue, '00.0')"/> </xsl:when> <!-- 小数部分长度≥2时,按2位小数格式化 --> <xsl:otherwise> <xsl:value-of select="format-number($rawValue, '00.00')"/> </xsl:otherwise> </xsl:choose> </xsl:copy> </xsl:template> </xsl:stylesheet>
输出效果
运行上述代码可以完全匹配期望输出:
<?xml version="1.0" encoding="UTF-8"?> <testvalues> <test>02.25</test> <test>02.2</test> <test>02.20</test> </testvalues>
扩展说明
如果输入存在无小数点的整数值(比如value="02"),substring-after会返回空串,长度为0,会默认走1位小数格式输出02.0,如果需要调整整数的输出格式,修改对应判断分支的逻辑即可。
内容的提问来源于stack exchange,提问作者Feargal Hogan
相关产品推荐
相关产品推荐

