首页 > 解决方案 > 在 XSLT 中添加两个科学数字

问题描述

我必须在 XSLT 中添加两个具有科学数值的变量。当我使用像这样的 xsl:with-param name="inputVal" select="($price1+$price2)" 时,我得到了 NAN。其中 Price1 = 1.0E7 和 Price2 = 1.0E8。我也有 Sum() 的问题。

这是我正在寻找 My XML 的示例:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
    <title>CD1</title>
    <price>1.0E7</price>
  </cd>
  <cd>
    <title>CD2</title>
    <price>1.1E7</price>
  </cd>
  <cd>
    <title>CD3</title>
    <price>1.2E7</price>
  </cd>
</catalog>

我的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Price</th>
      </tr>
      <xsl:for-each select="catalog/cd">
      <tr>
      <td>
       
      <xsl:value-of select="title"/></td>
        <td><xsl:call-template name="convertSciToNumString">
                                                    <xsl:with-param name="inputVal" select="price"/>
                                                </xsl:call-template></td>
      </tr>
     </xsl:for-each>
      <tr>
        <th>Total</th>
        <th><xsl:value-of select="sum(catalog/cd/price)"/></th>
      </tr>
    </table>
  </body>
  </html>
</xsl:template>
    <xsl:template name="convertSciToNumString" >
        <xsl:param name="inputVal" select="0"/>
        <xsl:variable name="vMantissa" select="substring-before($inputVal, 'E')"/>
        <xsl:variable name="vExponent" select="substring-after($inputVal, '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="$inputVal = ''">       
            </xsl:when>
            <xsl:when test="number($inputVal)=$inputVal">
                <xsl:value-of disable-output-escaping="no" select="format-number($inputVal, '##,###,###,###,###,###,##0.00')"/>
            </xsl:when>
            <xsl:when test="starts-with($vExponent,'-')">
                <xsl:value-of disable-output-escaping="no" select="format-number($vMantissa div $vFactor, '##,###,###,###,###,###,##0.00')"/>
            </xsl:when>
            <xsl:otherwise>         
                <xsl:value-of disable-output-escaping="no" select="format-number($vMantissa * $vFactor, '##,###,###,###,###,###,##0.00')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

我正在使用 1.0 版,并按照建议创建模板以将数据从科学格式转换为数字格式,我可以单独使用,但在某些情况下我必须使用 sum() 或 variable1 + variable2,我不是确定如何处理。

标签: xslt-1.0

解决方案


您尝试的主要问题是您的模板返回的是格式化字符串,而不是数字

另一件事是您需要分两次执行此操作:首先,将科学记数法值转换为数字;然后将得到的数字相加,并在必要时对它们进行格式化以供输出。

如果您使用的是 Apache Xalan 处理器,则可以通过使用 EXSLT math:power()扩展函数来简化此操作:

XSLT 1.0 (+ EXSLT)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
extension-element-prefixes="exsl math">

<xsl:template match="/catalog">
    <!-- FIRST PASS -->
    <xsl:variable name="cds-rtf">
        <xsl:for-each select="cd">
            <xsl:copy>
                <xsl:copy-of select="title"/>
                <price>
                    <xsl:variable name="significand" select="substring-before(price,'E')"/>
                    <xsl:variable name="magnitude" select="substring-after(price,'E')"/>
                    <xsl:value-of select="$significand * math:power(10, $magnitude)"/>
                </price>
            </xsl:copy>
        </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="cds" select="exsl:node-set($cds-rtf)/cd"/>
    <!-- OUTPUT -->
    <html>
        <body>
            <h2>My CD Collection</h2>
            <table border="1">
                <tr>
                    <th>Title</th>
                    <th>Price</th>
                </tr>
                <xsl:for-each select="$cds">
                    <tr>
                        <td>
                            <xsl:value-of select="title"/>
                        </td>
                        <td>
                            <xsl:value-of select="format-number(price, '#,###')"/>
                        </td>
                    </tr>
                </xsl:for-each>
                <tr>
                    <th>Total</th>
                    <th>
                        <xsl:value-of select="format-number(sum($cds/price), '#,###')"/>
                    </th>
                </tr>
            </table>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,这将产生:

结果(渲染)

在此处输入图像描述


推荐阅读