2

xs:decimal我有一个 XML 文档,其中应报告特定的小数位数保存在同级节点中。我目前正在努力寻找一种简单的方法来通过该format-number函数输出它。

我可以用其他一些函数构建一个图片字符串,但这对于应该是(至少在 imo 中)一个相对简单和常见的任务来说似乎非常冗长。

例如,我目前正在做的事情是这样的:

<xsl:value-of
 select="format-number(myNode/DecimalValue,
         concat('#0.', 
                string-join(for $i in 1 to myNode/DecimalPlaces return '0'))"
/>

有没有更好的办法?

4

2 回答 2

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)

于 2010-01-07T16:41:31.210 回答
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>
于 2010-01-07T17:11:01.680 回答