我有一个XML文档,其中应报告特定xs:decimal
的小数位数保存在同级节点中。我目前正在努力寻找一种通过format-number
函数输出的简单方法。
我可以用一些其他函数构建一个图片字符串,但这似乎非常冗长,应该(至少是imo)一个相对简单和常见的任务。
e.g。我目前正在做的是这样的事情:
<xsl:value-of
select="format-number(myNode/DecimalValue,
concat('#0.',
string-join(for $i in 1 to myNode/DecimalPlaces return '0'))"
/>
有更好的方法吗?
答案 0 :(得分:4)
非常好的问题!这通常意味着,我不知道答案,但我希望其他人这样做,因为这对我来说也是一种痛苦。
无论如何,我做了一些搜索,我认为round-half-to-even
函数可以解决问题(http://www.xqueryfunctions.com/xq/fn_round-half-to-even.html)
您的代码将变为:
<xsl:value-of
select="
round-half-to-even(
myNode/DecimalValue
, myNode/DecimalPlaces
)
"
/>
现在关闭一点切线: 对于使用XSLT 1.1或更低版本以及XPath 1的用户,可以使用:
<xsl:value-of
select="
concat(
substring-before(DecimalValue, '.')
, '.'
, substring(substring-after(DecimalValue, '.'), 1, DecimalPlaces -1)
, round(
concat(
substring(substring-after(DecimalValue, '.'), DecimalPlaces, 1)
, '.'
, substring(substring-after(DecimalValue, '.'), DecimalPlaces+1)
)
)
)
"
/>
当然,这段代码更糟比原版更好,但是如果有人知道如何解决XPath 1的原始问题并且有比这更好的想法,我很乐意听到。 (越来越多的时候,我希望世界完全跳过XML并立即转向JSON)
答案 1 :(得分:2)
<!-- use a generous amount of zeros in a top-level variable -->
<xsl:variable name="zeros" select="'000000000000000000000000000000000'" />
<!-- …time passes… -->
<xsl:value-of select="
format-number(
myNode/DecimalValue,
concat('#0.', substring($zeros, 1, myNode/DecimalPlaces))
)
" />
您可以将其抽象为模板:
<!-- template mode is merely to prevent collisions with other templates -->
<xsl:template match="myNode" mode="FormatValue">
<xsl:value-of select="
format-number(
DecimalValue,
concat('#0.', substring($zeros, 1, DecimalPlaces))
)
" />
</xsl:template>
<!-- call like this -->
<xsl:apply-templates select="myNode" mode="FormatValue" />
您还可以创建一个命名模板,并在调用它时使用XSLT上下文节点。如果这对您来说可取决于您的输入文档和需求。
<xsl:template name="FormatValue">
<!-- same as above -->
</xsl:template>
<!-- call like this -->
<xsl:for-each select="myNode">
<xsl:call-template name="FormatValue" />
</xsl:for-each>