在 Xpath/XSLT 中将 xs:double 转换为 xs:decimal 自定义与内置



我过去没有处理过敏感号码,所以想检查一下。我有输入,表示为 xs:double:

<do:amount>1.60</do:amount>

XSL/XPath:

<dec:amount><xsl:value-of select="xs:decimal(do:amount)"/></dec:amount>

输出应为:

<dec:amount>1.60</dec:amount>

编写一个将 do:amount 视为文本,按点字符分割,然后将其转换为十进制的自定义函数有什么好处吗?是否有任何我应该注意的情况,其中铸造或计算可能不精确?

似乎将

xs:double s 转换为 xs:decimal 很容易导致浮点后有很多数字的数字,例如当我评估时

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs" default-validation="lax">
<xsl:output indent="yes"/>
<xsl:import-schema>
  <xs:schema>
    <xs:element name="double-amount" type="xs:double"/>
    <xs:element name="dec-amount" type="xs:decimal"/>
  </xs:schema>
</xsl:import-schema>
<xsl:template match="/" name="main">
  <xsl:variable name="doubles" as="element(double-amount)*">
    <xsl:for-each select="1 to 10">
      <double-amount>
        <xsl:value-of select="1E0 + 1E-1 * ."/>
      </double-amount>
    </xsl:for-each>
  </xsl:variable>
  <xsl:copy-of select="$doubles"/>
  <xsl:apply-templates select="$doubles"/>
  <xsl:apply-templates select="$doubles" mode="cast"/>
</xsl:template>
<xsl:template match="double-amount">
  <dec-amount>
    <xsl:value-of select="."/>
  </dec-amount>
</xsl:template>
<xsl:template match="double-amount" mode="cast">
  <dec-amount>
    <xsl:value-of select="xs:decimal(.)"/>
  </dec-amount>
</xsl:template>
</xsl:stylesheet>

使用撒克逊 9.6 EE 或撒克逊 9.5 EE(见 http://xsltransform.net/gWmuiJj),则结果为

<double-amount>1.1</double-amount>
<double-amount>1.2</double-amount>
<double-amount>1.3</double-amount>
<double-amount>1.4</double-amount>
<double-amount>1.5</double-amount>
<double-amount>1.6</double-amount>
<double-amount>1.7000000000000002</double-amount>
<double-amount>1.8</double-amount>
<double-amount>1.9</double-amount>
<double-amount>2</double-amount>
<dec-amount>1.1</dec-amount>
<dec-amount>1.2</dec-amount>
<dec-amount>1.3</dec-amount>
<dec-amount>1.4</dec-amount>
<dec-amount>1.5</dec-amount>
<dec-amount>1.6</dec-amount>
<dec-amount>1.7000000000000002</dec-amount>
<dec-amount>1.8</dec-amount>
<dec-amount>1.9</dec-amount>
<dec-amount>2</dec-amount>
<dec-amount>1.100000000000000088817841970012523233890533447265625</dec-amount>
<dec-amount>1.1999999999999999555910790149937383830547332763671875</dec-amount>
<dec-amount>1.3000000000000000444089209850062616169452667236328125</dec-amount>
<dec-amount>1.399999999999999911182158029987476766109466552734375</dec-amount>
<dec-amount>1.5</dec-amount>
<dec-amount>1.600000000000000088817841970012523233890533447265625</dec-amount>
<dec-amount>1.70000000000000017763568394002504646778106689453125</dec-amount>
<dec-amount>1.8000000000000000444089209850062616169452667236328125</dec-amount>
<dec-amount>1.899999999999999911182158029987476766109466552734375</dec-amount>
<dec-amount>2</dec-amount>

这表明执行xs:decimal(.)而不是简单地. xsl:value-of会导致浮点后有很多数字的数字,这可能是原始xs:double的精确xs:decimal表示,但可能不是您想要存储的值。所以我想知道你是否通过做xs:decimal(.)而不是简单地复制价值来获得任何东西。

最新更新