Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 在xsl中格式化科学数字表示_Xslt_Numbers_Format - Fatal编程技术网

Xslt 在xsl中格式化科学数字表示

Xslt 在xsl中格式化科学数字表示,xslt,numbers,format,Xslt,Numbers,Format,我的XML中有以下值-1.8959581529998104E-4。我想将其格式化为它应该使用XSL给出的确切数字-0.000189595815299981 格式编号(-1.8959581529998104E-4,'0.000000;-0.000000')给出了NaN 有什么想法吗 干杯 Andez不支持科学记数法。XSLT1.0 此:编号('-1.8959581529998104E-4') 结果:NaN 此:编号('-0.000189595815299981') 结果:-0.0001895958

我的XML中有以下值-1.8959581529998104E-4。我想将其格式化为它应该使用XSL给出的确切数字-0.000189595815299981

格式编号(-1.8959581529998104E-4,'0.000000;-0.000000')给出了NaN

有什么想法吗

干杯


Andez不支持科学记数法。XSLT1.0

此:
编号('-1.8959581529998104E-4')
结果:
NaN

此:
编号('-0.000189595815299981')
结果:
-0.000189595815299981

XSLT2.0支持科学表示法

<xsl:template name="convertSciToNumString" >
    <xsl:param name="inputVal" select="0"/>
    <xsl:variable name="vExponent" select="substring-after($inputVal,'E')"/>
    <xsl:variable name="vMantissa" select="substring-before($inputVal,'E')"/>
    <xsl:variable name="vFactor"
         select="substring('100000000000000000000000000000000000000000000',
                           1, substring($vExponent,2) + 1)"/>
    <xsl:choose>
        <xsl:when test="number($inputVal)=$inputVal">
            <xsl:value-of select="$inputVal"/>
        </xsl:when>
        <xsl:when test="starts-with($vExponent,'-')">
            <xsl:value-of select="format-number($vMantissa div $vFactor, '#0.#############')"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="format-number($vMantissa * $vFactor, '#0.#############')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
此:
编号('-1.8959581529998104E-4')
结果:
-0.000189595815299981

编辑:一个非常简单的XSLT 1.0解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="number[substring-after(.,'E')]">
        <xsl:variable name="vExponent" select="substring-after(.,'E')"/>
        <xsl:variable name="vMantissa" select="substring-before(.,'E')"/>
        <xsl:variable name="vFactor"
             select="substring('100000000000000000000000000000000000000000000',
                               1, substring($vExponent,2) + 1)"/>
        <xsl:choose>
            <xsl:when test="starts-with($vExponent,'-')">
                <xsl:value-of select="$vMantissa div $vFactor"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$vMantissa * $vFactor"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

刚刚在Linux下使用版本1.1.24中的libxslt1.1使用xsltproc尝试了这一点:


XSLT1.1现在能够以指数/科学格式阅读,即使没有任何专门的模板,它似乎也能简单地工作:-)

这是基于user357812的答案。但我让它像一个函数一样,处理非科学的符号

<xsl:template name="convertSciToNumString" >
    <xsl:param name="inputVal" select="0"/>
    <xsl:variable name="vExponent" select="substring-after($inputVal,'E')"/>
    <xsl:variable name="vMantissa" select="substring-before($inputVal,'E')"/>
    <xsl:variable name="vFactor"
         select="substring('100000000000000000000000000000000000000000000',
                           1, substring($vExponent,2) + 1)"/>
    <xsl:choose>
        <xsl:when test="number($inputVal)=$inputVal">
            <xsl:value-of select="$inputVal"/>
        </xsl:when>
        <xsl:when test="starts-with($vExponent,'-')">
            <xsl:value-of select="format-number($vMantissa div $vFactor, '#0.#############')"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="format-number($vMantissa * $vFactor, '#0.#############')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

用法:

<xsl:template match="X">
    <X>
        <xsl:call-template name="convertSciToNumString">
            <xsl:with-param name="inputVal" select="text()"/>
        </xsl:call-template>
    </X>    
</xsl:template>


这应该处理科学记数法和十进制值的混合。

没有模板的另一种可能的解决方法:

<xsl:stylesheet version="1.0" ... xmlns:java="http://xml.apache.org/xslt/java">
...
<xsl:value-of select="format-number(java:java.lang.Double.parseDouble('1E-6'), '0.000')"/>

...

在一个特定场景中确定
vFactor
时,上述答案中的逻辑似乎不正确

如果
vExponent
是一个单位数正数(前面没有“+”号),则
vFactor
被设置为空字符串。这是因为假设
vExponent
的第一个字符是加号/减号,因此第二个字符之后的字符是有意义的。然后将
vmantisa
变量乘以一个空字符串,结果模板输出
NaN

如果
vExponent
是一个多位数正数(前面没有“+”号),则
vFactor
被设置为一个不正确的值。由于上述假设,忽略第一位数字,然后将
vmantisa
乘以不正确的
vFactor

所以,我对之前发布的代码做了一些修改,以便它能够处理表单的科学编号:2E-4、2E+4和2E4

<xsl:template name="convertSciToNumString" >
    <xsl:param name="inputVal" select="0"/>
    <xsl:variable name="vMantissa" select="substring-before(., 'E')"/>
    <xsl:variable name="vExponent" select="substring-after(., 'E')"/>
    <xsl:variable name="vExponentAbs" select="translate($vExponent, '-', '')"/>
    <xsl:variable name="vFactor" select="substring('100000000000000000000000000000000000000000000', 1, substring($vExponentAbs, 1) + 1)"/>
    <xsl:choose>
        <xsl:when test="number($inputVal)=$inputVal">
            <xsl:value-of select="$inputVal"/>
        </xsl:when>
        <xsl:when test="starts-with($vExponent,'-')">
            <xsl:value-of select="format-number($vMantissa div $vFactor, '#0.#############')"/>
        </xsl:when>
        <xsl:otherwise>         
            <xsl:value-of select="format-number($vMantissa * $vFactor, '#0.#############')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


@Alejandro,再次感谢!!!我正试图在IDE中使用VS2008实现转换。我需要做些什么来强制它使用xsl的2.0版本吗?即?仅在MSDN论坛上查看,VS2008不支持2.0版:-(@Andez:看起来你可以使用XSLT 2.0实现,但你不能将它们与VS.Link:是的,回答得很好@Alejandro。这对我来说非常有用。再次感谢。当正指数前面没有“+”符号(例如2E4)时,此答案中发布的模板无法正确处理正指数),请参阅下面我的修改版本:适用于Java,而不是其他XSLT实现。:)如果正指数前面没有“+”符号(例如2E4),则此答案中发布的模板无法正确处理正指数,请参阅下面我的修改版本:但这会破坏具有“+”符号的指数(至少在mono的XSLT处理器中)。如果您将行更改为select=“translate(translate($vExponent),-,,,,,,,,,,,,,”,它会修复错误。我会进行编辑,但这看起来很粗鲁。
<xsl:template name="convertSciToNumString" >
    <xsl:param name="inputVal" select="0"/>
    <xsl:variable name="vMantissa" select="substring-before(., 'E')"/>
    <xsl:variable name="vExponent" select="substring-after(., 'E')"/>
    <xsl:variable name="vExponentAbs" select="translate($vExponent, '-', '')"/>
    <xsl:variable name="vFactor" select="substring('100000000000000000000000000000000000000000000', 1, substring($vExponentAbs, 1) + 1)"/>
    <xsl:choose>
        <xsl:when test="number($inputVal)=$inputVal">
            <xsl:value-of select="$inputVal"/>
        </xsl:when>
        <xsl:when test="starts-with($vExponent,'-')">
            <xsl:value-of select="format-number($vMantissa div $vFactor, '#0.#############')"/>
        </xsl:when>
        <xsl:otherwise>         
            <xsl:value-of select="format-number($vMantissa * $vFactor, '#0.#############')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>