2010-07-29 68 views
2

期间保留的处理过程中位数输入 - >号 - >输出对于该XSLT:XSLT处理

<xsl:variable name="source0" select="number(num2)"/> 
    <xsl:variable name="source1" select="number(num3)"/> 
    s0 plain: <xsl:value-of select="$source0"/> 
    s1 plain: <xsl:value-of select="$source1"/> 
    test11: <xsl:value-of select="format-number($source0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($source0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($source1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($source1, '#.###############')"/> 

对于XML:

<num2>123456.1234</num2> 
<num3>1234567.1234</num3> 

我得到如下的输出(使用撒克逊9.2,XSLT 2.0)

s0 plain: 123456.1234 
    s1 plain: 1.2345671234E6 
    test11: 123456.1 
    test12: 123456.123399999996764 
    test21: 1234567.1 
    test22: 1234567.123399999924004 

首先......我很好奇为什么它突然标准和科学记数法之间时,它EXCE切换在小数点左边编辑6位数字?这是我的问题,我想避免科学记数法。在其他各种问题之后,我发现显然我坚持把格式编号放在任何地方。

但格式编号似乎也不工作。尽管事实上“s1 plain”的输出证明了处理器已知有效数字的数目(我知道转换为double和back会失去精度,但在这种转换之后有正确的数字,所以...?),似乎没有办法以标准的非科学记数法输出该值。在那儿?

+0

好问题(+1)。查看我的答案以获得最高精度的解决方案。 – 2010-07-30 04:27:01

+0

双字符串转换的XSLT 2.0规范说,如果值超出范围1e-6到1e + 6,应该使用指数表示法。当然,这些分界点完全是任意的,但是你不希望1e215用慢速写出来...... – 2011-01-14 20:38:19

+0

认为“处理器已知有效数字的数量”是错误的。如果您想更多地了解所使用的算法,Saxon的转换基于这篇着名的论文:http://portal.acm.org/citation.cfm?id=93559适应XPath规范的要求。 – 2011-01-14 20:41:16

回答

2

这是我的问题,我想避免 科学记数法。各种 其他问题后,我发现显然 我坚持把格式编号 无处不在。

但是格式编号并不出现在 工作。

显然,您没有使用XSLT 2.0/XPath 2.0的相应功能

这种转变:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output method="text"/> 

<xsl:template match="/*"> 
    <xsl:variable name="vs0" as="xs:decimal" 
    select="xs:decimal(num2)"/> 

    <xsl:variable name="vs1" as="xs:decimal" 
    select="xs:decimal(num3)"/> 

    s0 plain: <xsl:value-of select="$vs0"/> 
    s1 plain: <xsl:value-of select="$vs1"/> 
    test11: <xsl:value-of select="format-number($vs0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($vs0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($vs1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($vs1, '#.###############')"/> 

</xsl:template> 
</xsl:stylesheet> 

当这个XML文档施加:

<nums> 
    <num2>123456.1234</num2> 
    <num3>1234567.1234</num3> 
</nums> 

可生产精确的结果

s0 plain: 123456.1234 
s1 plain: 1234567.1234 
test11: 123456.1 
test12: 123456.1234 
test21: 1234567.1 
test22: 1234567.1234 

结论:当需要高精度时,总是尝试使用xs:decimal数据类型。

+0

+1好答案! @taotree:这是我在另一个问题中写作“铸造”并使用“内置数据类型构造函数” – 2010-07-30 13:42:00

+0

实际上,使用xs:decimal时根本不需要使用格式编号。所有你需要做的就是将它转换为xs:decimal,并且它总是以十进制(非科学)符号输出。我确实需要检查空字符串,因为number()是宽容的,但是xs:decimal()不是。 if(string-length(normalize-space($ value))> 0)then xs:decimal($ value)else number($ value) – mentics 2010-07-30 20:19:53