在for-each循环中减去两个值

时间:2019-09-25 08:36:20

标签: xml xslt

我正在尝试在for-each循环中减去两个值MaxTaxFreeValue-Reduction,但结果是NaN。我该如何解决?

<xsl:for-each select="Position">
    <TR CLASS="position leftRightPadding">
        <TD />
        <TD CLASS="alignRight" STYLE="min-width:85px;"><xsl:value-of select="Date" /></TD>
        <TD CLASS="alignLeft"><xsl:value-of select="Text" /></TD>
        <TD><xsl:value-of select="MaxTaxFreeValue"/></TD>
        <TD><xsl:value-of select="Reduction"/></TD>
        <TD><xsl:value-of select=number("MaxTaxFreeValue" - "Reduction")/></TD>
        <TD><xsl:value-of select="Account"/></TD>
        <TD><xsl:value-of select="ValueAddedTaxPercentValue"/></TD>
        <TD><xsl:value-of select="KindOfPayment"/></TD>
        <xsl:for-each select="FreeFields/FreeField">
            <TD class="alignLeft"><xsl:value-of select="Value" disable-output-escaping="yes"/></TD>
        </xsl:for-each>
    </TR>
</xsl:for-each>

1 个答案:

答案 0 :(得分:0)

在XSLT / XPATH中,数字必须使用句号作为小数点,而不是某些区域性中使用的逗号。它也不能包含任何货币符号(请参见https://www.w3.org/TR/xpath-10/#NT-Number

因此,您需要从元素中删除任何货币符号或空格,然后转换为数字。如果您的值仅限于包含的值,则可以执行此操作

<xsl:value-of select="number(translate(MaxTaxFreeValue, ',€ ', '.')) 
                        + number(translate(Reduction, ',€ ', '.'))" />

请注意此处使用+,而不是-。如果您从另一个数字中减去一个负数,则与添加该数字的正数相同,因此,如果Reduction始终为负数,那么我认为您实际上需要在这里加法。

请参见http://xsltfiddle.liberty-development.net/94AbWAN作为示例。请注意,这仅适用于欧元货币符号,并且还假定元素为非空。

另一方面,如果您要处理任何意外的符号,或者元素可能为空,则可能需要创建一个命名模板来进行转换,因为您需要对double-翻译:

<xsl:template name="convertToNumber">
  <xsl:param name="element" />
  <xsl:choose>
      <xsl:when test="normalize-space($element)">
          <xsl:value-of select="translate($element, concat(',', translate($element, '-01234567890', '')), '.')" />
      </xsl:when>
      <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

嵌套的转换将返回字符串中的非数字字符,然后将其从主字符串中删除。

然后,您可以使用称为此模板的变量来进行计算

<xsl:variable name="maxTaxFreeValue">
    <xsl:call-template name="convertToNumber">
        <xsl:with-param name="element" select="MaxTaxFreeValue" />
    </xsl:call-template>
</xsl:variable>
<xsl:variable name="reduction">
    <xsl:call-template name="convertToNumber">
        <xsl:with-param name="element" select="Reduction" />
    </xsl:call-template>
</xsl:variable>
<xsl:value-of select="number($maxTaxFreeValue) + number($reduction)" />

有关示例,请参见http://xsltfiddle.liberty-development.net/94AbWAN/1

当然,如果可以使用XSLT 2.0,则可以使用函数代替命名模板以及replace语句。

<xsl:function name="my:convertToNumber" as="xs:decimal">
  <xsl:param name="element" />
  <xsl:value-of select="if (normalize-space($element)) then replace(replace($element, ',', '.'), '[^\.\-0-9]', '') else 0" />
</xsl:function>

有关示例,请参见http://xsltfiddle.liberty-development.net/94AbWAN/2