在XSL表中获取Sum之前格式化数字

时间:2015-10-14 19:45:38

标签: xml xslt xslt-1.0

这是我的XML:

<OutboundPaymentInstruction>
  <OutboundPayment>
   <Extend2>
      <SHOW_CONVERTED_AMOUNT>Y</SHOW_CONVERTED_AMOUNT>
      <BASE_AMOUNT>2150.1435</BASE_AMOUNT>
    </Extend2>
  </OutboundPayment>
  <OutboundPayment>
    <Extend2>
      <SHOW_CONVERTED_AMOUNT>Y</SHOW_CONVERTED_AMOUNT>
      <BASE_AMOUNT>8258.4375</BASE_AMOUNT>
    </Extend2>
  </OutboundPayment>
  <OutboundPayment>
    <Extend2>
      <SHOW_CONVERTED_AMOUNT>Y</SHOW_CONVERTED_AMOUNT>
      <BASE_AMOUNT>4085.1105</BASE_AMOUNT>
    </Extend2>
  </OutboundPayment>
 </OutboundPaymentInstruction>

这是XSL:

<xsl:template match="OutboundPaymentInstruction">
  <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <GrpHdr>
      <CtrlSum>
        <xsl:if test="(/OutboundPaymentInstruction/OutboundPayment/Extend2/SHOW_CONVERTED_AMOUNT='Y')">
          <xsl:value-of select="sum(format-number(/OutboundPaymentInstruction/OutboundPayment/Extend2/BASE_AMOUNT,'#.00'))"></xsl:value-of>
        </xsl:if>
      </CtrlSum>
    </GrpHdr>
  </Document>
</xsl:template>

我想在XSL中获取总和之前将数字格式化为2位小数。例如,我想添加2150.14,8258.43和4085.11而不是它们的4位十进制格式。是否可以将它们转换为2位小数,然后取其总和。请帮助

加了:

这个XSL是由其他人开发的,后来他们发现了一个bug,这就是为什么要求我解决这个问题。显然,我对XML或XSL一无所知。现在的问题是,假设输入金额是45.678和23.456,但在XSL中我们将这些金额截断为2位小数并将其作为45.67和23.45以及它们的总和(69.13)发送到银行。现在银行正在添加个别金额(69.12)并将其与给定金额(69.13)进行比较。这就是为什么我想在添加它们之前格式化数字而不是在总和之后。

3 个答案:

答案 0 :(得分:0)

试试这个:

<CtrlSum>
    <xsl:variable name="var">
        <xsl:for-each select="OutboundPayment/Extend2[SHOW_CONVERTED_AMOUNT='Y']/BASE_AMOUNT">
            <value>
                <xsl:value-of select="format-number(., '#.00')"/>
            </value>
        </xsl:for-each>
    </xsl:variable>

    <xsl:value-of select="sum(exsl:node-set($var)/value)"/>
</CtrlSum>

在XSLT-1.0中,我们需要一些node-set函数。例如,来自EXSLT。为此,我们需要指定xmlns:

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

答案 1 :(得分:0)

在XSLT 2.0中:sum(//element/round-half-to-even(., 2))

在XSLT 1.0中,format-number()执行的舍入没有精确指定,并且这不是函数的用途;舍入到小数点后两位的更好方法可能是round($x*100) div 100。但无论你使用什么方法,你都会遇到这样的问题,即在XSLT 1.0中没有数字集合,只有节点集合,所以要总结在源文档中没有出现的任何内容,你必须创建新的包含计算数字的节点,要对这些节点求和,您需要exslt:node-set()函数将结果树片段转换为节点集。

答案 2 :(得分:0)

  

现在的问题是,假设输入金额是45.678和23.456,但是   在XSL中,我们将这些数量截断为2位小数并发送给   银行为45.67和23.45及其金额(69.13)。现在银行正在加入   个人数量(69.12)并将其与给定数量进行比较   总和(69.13)。

如果你想截断 - 即向下舍入 1 - 在给定它们之前给定的数字为2位小数,试试这样:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/OutboundPaymentInstruction">
    <xsl:variable name="truncated-amounts">
        <xsl:for-each select="OutboundPayment/Extend2[SHOW_CONVERTED_AMOUNT='Y']">
            <amount>
                <xsl:value-of select="floor(100 * BASE_AMOUNT) div 100"/>
            </amount>
        </xsl:for-each>
    </xsl:variable>
    <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <GrpHdr>
            <CtrlSum>
                <xsl:value-of select="sum(exsl:node-set($truncated-amounts)/amount)"/>
            </CtrlSum>
        </GrpHdr>
    </Document>
</xsl:template>

</xsl:stylesheet>

测试输入:

<OutboundPaymentInstruction>
  <OutboundPayment>
   <Extend2>
      <SHOW_CONVERTED_AMOUNT>Y</SHOW_CONVERTED_AMOUNT>
      <BASE_AMOUNT>45.678</BASE_AMOUNT>
    </Extend2>
  </OutboundPayment>
  <OutboundPayment>
    <Extend2>
      <SHOW_CONVERTED_AMOUNT>N</SHOW_CONVERTED_AMOUNT>
      <BASE_AMOUNT>9999.9999</BASE_AMOUNT>
    </Extend2>
  </OutboundPayment>
  <OutboundPayment>
    <Extend2>
      <SHOW_CONVERTED_AMOUNT>Y</SHOW_CONVERTED_AMOUNT>
      <BASE_AMOUNT>23.456</BASE_AMOUNT>
    </Extend2>
  </OutboundPayment>
 </OutboundPaymentInstruction>

<强>结果:

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <GrpHdr>
    <CtrlSum>69.12</CtrlSum>
  </GrpHdr>
</Document>

(1)截断和向下舍入(即向负无穷大)对于数字是相同的,但对于数字则不相同。如果您的输入可能包含负数,并且您想要截断它们 - IOW,如果您始终想要舍入为零 - 您必须使用ceiling()代替floor()