我一直在尝试找出如何使用 Muenchian 分组对分组和求和值进行总计,但无济于事。
这是我的分组键:
<xsl:key name="kRcdGroup" match="Export/Record" use="concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode))"/>
vb 函数仅返回传递给它的两个值中的一个或另一个。
我创建了这个变量作为求和媒介:
<xsl:variable name="vkeyGroup" select="key('kRcdGroup', concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode))) "/>
这是一个管道分隔的文本输出,我正在 for-each 循环中进行求和:
<xsl:for-each select="Export/Record[generate-id() = generate-id(key('kRcdGroup',concat(generate-id(..), AccountNo, Description, vb:GetOverrideCode(DeptOverride,LedgerCode)))[1])] ">
到目前为止,输出工作正常。但是,客户端要求添加页脚。他们想要所有这些分组/求和值的摘要。
此输出用于将数据上传到数据库,因此它必须采用这种荒谬的格式。 01 是页眉,02 是详细输出,99 是页脚。 (注意:页眉之后或页脚之前不应该有空行,我必须这样做才能更具可读性。)
01|CA|付款2082027||
02|1|1|||23|0736|0704010000|0736131554|PAYR||||0|0704010000||||V0|13864.08|CAD||||CAN Flex CASH_0001|||CP||||| CAN Flex 现金||40|0736|0736131554|||||||||||||||||||||||||||||||||| 02|1|2|||23|0736|0701000000|0736131554|PAYR||||0|0701000000||||V0|149480.33|CAD||||CAN奖金_0002|||CP|||||CAN奖金||40|0736|0736131554||||||||||||||||||||||||||||||||| 02|1|3|||23|0736|0700793000|0736131554|PAYR||||0|0700793000||||V0|74941.42|CAD||||CAN TXB RRSP_0003|||CP|||||CAN TXB RRSP||40|0736|0736131554|||||||||||||||||||||||||||||||||
99|238285.83
这里是 xml 的几个节点:
<Export>
<Record>
<AccountNo><![CDATA[0700103000]]></AccountNo>
<Onsite></Onsite>
<Amount> 47916.63</Amount>
<PayDate>15062023</PayDate>
<PayDateCA>06152023</PayDateCA>
<PPStartDate>20230601</PPStartDate>
<PPEndDate>06/15/2023</PPEndDate>
<PPEndDateCA>20230615</PPEndDateCA>
<Description><![CDATA[CAN Regular ]]></Description>
<Category>Earning</Category>
<Desc><![CDATA[CAN Regular]]></Desc>
<EmpNumber>6001237</EmpNumber>
<EmpFirstName><![CDATA[Elia]]></EmpFirstName>
<EmpLastName><![CDATA[DiLoreto]]></EmpLastName>
<DeptName>0736131554</DeptName>
<DeptLedgerCode></DeptLedgerCode>
<OnSiteName><![CDATA[0736131554 - Toronto Office - 0736]]></OnSiteName>
<SiteCode><![CDATA[]]></SiteCode>
<DeptOverride></DeptOverride>
<LedgerCode><![CDATA[0736131554]]></LedgerCode>
<Constant1>ERN</Constant1>
<Constant2></Constant2>
<Constant3></Constant3>
<Constant4></Constant4>
<Constant5></Constant5>
<Filler1><![CDATA[ ]]></Filler1>
<Filler2><![CDATA[ ]]></Filler2>
<LegalEntity>Deutsche Bank AG CA</LegalEntity>
<EmpType>FT</EmpType>
</Record>
<Record>
<AccountNo><![CDATA[0700793000]]></AccountNo>
<Onsite></Onsite>
<Amount> 8833.12</Amount>
<PayDate>15062023</PayDate>
<PayDateCA>06152023</PayDateCA>
<PPStartDate>20230601</PPStartDate>
<PPEndDate>06/15/2023</PPEndDate>
<PPEndDateCA>20230615</PPEndDateCA>
<Description><![CDATA[CAN TXB RRSP ]]></Description>
<Category>Earning</Category>
<Desc><![CDATA[CAN TXB RRSP]]></Desc>
<EmpNumber>6001237</EmpNumber>
<EmpFirstName><![CDATA[Elia]]></EmpFirstName>
<EmpLastName><![CDATA[DiLoreto]]></EmpLastName>
<DeptName>0736131554</DeptName>
<DeptLedgerCode></DeptLedgerCode>
<OnSiteName><![CDATA[0736131554 - Toronto Office - 0736]]></OnSiteName>
<SiteCode><![CDATA[]]></SiteCode>
<DeptOverride></DeptOverride>
<LedgerCode><![CDATA[0736131554]]></LedgerCode>
<Constant1>MEM</Constant1>
<Constant2></Constant2>
<Constant3></Constant3>
<Constant4></Constant4>
<Constant5></Constant5>
<Filler1><![CDATA[ ]]></Filler1>
<Filler2><![CDATA[ ]]></Filler2>
<LegalEntity>Deutsche Bank AG CA</LegalEntity>
<EmpType>FT</EmpType>
</Record>
</Export>
for-each 循环中的 Amount 值将其绝对值与指示符号的 neg (40) 或 pos (50) 标志相加。
<xsl:choose>
<xsl:when test="sum($vkeyGroup/Amount) > 0">
<xsl:value-of select="format-number(sum($vkeyGroup/Amount),'#.00')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number(sum($vkeyGroup/Amount)*-1,'#.00')"/>
</xsl:otherwise>
</xsl:choose>
我尝试创建第二个键来按支付日期汇总货币值,该值在每条记录上都相同,但由于货币值可能是正值或负值,因此在按支付日期分组时,其总和会有所不同。我需要能够总结 Amount 字段的绝对值,以便它与 for-each 循环中的值的总和相匹配。
我联系了 Jeni Tennison,但还没有收到回复——我正面临着解决这个问题的压力。任何帮助/示例将不胜感激。我正在通过你们的帮助学习,但我还有很长的路要走。接下来,我需要了解如何使用模板:)。
非常感谢,格雷格
我仍然在努力理解这里需要应用的逻辑是什么。
也许这个简化的示例可以有所帮助:
XML
<entries>
<entry>
<group>A</group>
<amount>-50</amount>
</entry>
<entry>
<group>A</group>
<amount>25</amount>
</entry>
<entry>
<group>B</group>
<amount>80</amount>
</entry>
<entry>
<group>B</group>
<amount>-20</amount>
</entry>
<entry>
<group>C</group>
<amount>15</amount>
</entry>
</entries>
XSLT 1.0 + EXSLT node-set() 扩展函数
<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:key name="entry-by-group" match="entry" use="group" />
<xsl:template match="/entries">
<!-- first pass -->
<xsl:variable name="subtotals">
<xsl:for-each select="entry[count(. | key('entry-by-group', group)[1]) = 1]">
<subtotal group="{group}">
<xsl:variable name="subtotal" select="sum(key('entry-by-group', group)/amount)"/>
<!-- output absolute value -->
<xsl:value-of select="translate($subtotal, '-', '')"/>
</subtotal>
</xsl:for-each>
</xsl:variable>
<!-- final output -->
<output>
<xsl:copy-of select="$subtotals"/>
<total>
<xsl:value-of select="sum(exsl:node-set($subtotals)/subtotal)"/>
</total>
</output>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<output>
<subtotal group="A">25</subtotal>
<subtotal group="B">60</subtotal>
<subtotal group="C">15</subtotal>
<total>100</total>
</output>
这似乎遵循您描述的过程,尽管我不明白这有什么用处。