这是我的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)进行比较。这就是为什么我想在添加它们之前格式化数字而不是在总和之后。
答案 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()
。