我有一个要求,我需要根据不同部分的两个不同值显示差异金额(<TotalAmount>
)。输入xml如下:
<TXLife xmlns="http://ACORD.org/Standards/Life/2">
<TXLifeRequest>
<FundCode>LTRW00</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Cr</ReversalInd>
<TotalAmount>1600</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<FundCode>LTRW00</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Dr</ReversalInd>
<TotalAmount>350</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<FundCode>LUL500</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Cr</ReversalInd>
<TotalAmount>500</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<FundCode>LUL500</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Dr</ReversalInd>
<TotalAmount>800</TotalAmount>
</TXLifeRequest>
</TXLife>
从上面的xml中,找到差量的标准是<FundCode>
和<AccountNumber>
。如果任何部分具有相同的<FundCode>
和<AccountNumber>
,则检索<TotalAmount>
并查找差异。
例如上面的xml:-
LTRW00和34142有两个相同<fundcode>
和<Accountnumber>
的section。现在<TotalAmount>
的差值是1250(1600 - 250)。我还需要在其他部分重复这个逻辑。
所以最终输出的xml应该是这样的:
<TXLife xmlns="http://ACORD.org/Standards/Life/2">
<TXLifeRequest>
<FundCode>LTRW00</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Cr</ReversalInd>
<TotalAmount>1250</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<FundCode>LUL500</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Dr</ReversalInd>
<TotalAmount>300</TotalAmount>
</TXLifeRequest>
</TXLife>
如果你观察到<ReversalInd>
是CR/DR,应该根据最高TotalAmount值来识别。
我已经应用了下面的xslt,但是没有输出。对如何在xslt 1.0中实现有什么想法吗?大大赞赏。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ns="http://ACORD.org/Standards/Life/2">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/ns:TXLife/ns:TXLifeRequest">
<xsl:element name="TXLife" namespace="http://ACORD.org/Standards/Life/2">
<xsl:call-template name="balance">
<xsl:with-param name="total" select="ns:TotalAmount"></xsl:with-param>
</xsl:call-template>
<xsl:copy-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template name="balance">
<xsl:param name="total"></xsl:param>
<xsl:variable name="reminder" select="0"></xsl:variable>
<xsl:variable name="val1">
<xsl:value-of select="$total[1]"/>
</xsl:variable>
<xsl:variable name="val2">
<xsl:value-of select="$total[position() > 1]"/>
</xsl:variable>
<xsl:if test="$val1 > $val2">
<remainingAmount><xsl:value-of select="$val1 - $val2"/></remainingAmount>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
尝试以下基于Muenchian分组的解决方案。TXLifeRequest按FundCode和AccountNumber分组。
即使组中有两个以上的条目也可以工作。组输出(特别是ReversalInd)的所有数据都来自TotalAmount最高的那个。TotalAmount的值为第一个(最高)TotalAmount与其余的TotalAmount之差。
它也考虑请求:"而且,如果您观察到CR/DR应该基于最高TotalAmount值来识别。"
xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kTXLifeRequest" match="ns:TXLifeRequest" use="concat(ns:FundCode,'#',ns:AccountNumber)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select=
"ns:TXLifeRequest[generate-id() = generate-id(key('kTXLifeRequest',concat(ns:FundCode,'#',ns:AccountNumber))[1])]" >
<xsl:copy>
<xsl:variable name="group"
select="key('kTXLifeRequest',concat(current()/ns:FundCode,'#',current()/ns:AccountNumber))" />
<xsl:for-each select= "$group" >
<xsl:sort select="ns:TotalAmount" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:apply-templates select="*[local-name() != 'TotalAmount']" />
<TotalAmount>
<xsl:value-of select="ns:TotalAmount - sum($group/ns:TotalAmount)+ ns:TotalAmount" />
</TotalAmount>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
将生成以下输出:
<TXLife xmlns="http://ACORD.org/Standards/Life/2">
<TXLifeRequest>
<FundCode>LTRW00</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Cr</ReversalInd>
<TotalAmount xmlns="">1250</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<FundCode>LUL500</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Dr</ReversalInd>
<TotalAmount xmlns="">300</TotalAmount>
</TXLifeRequest>
</TXLife>
更新计算GrandTotal的额外请求:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kTXLifeRequest" match="ns:TXLifeRequest" use="concat(ns:FundCode,'#',ns:AccountNumber)" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select=
"ns:TXLifeRequest[generate-id() = generate-id(key('kTXLifeRequest',concat(ns:FundCode,'#',ns:AccountNumber))[1])]" >
<xsl:copy>
<xsl:variable name="group"
select="key('kTXLifeRequest',concat(current()/ns:FundCode,'#',current()/ns:AccountNumber))" />
<xsl:for-each select= "$group" >
<xsl:sort select="ns:TotalAmount" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:apply-templates select="*[local-name() != 'TotalAmount']" />
<TotalAmount>
<xsl:value-of select="ns:TotalAmount - sum($group/ns:TotalAmount)+ ns:TotalAmount" />
</TotalAmount>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
<GrandTotal>
<xsl:call-template name="totalSum">
<xsl:with-param name="groups"
select=
"ns:TXLifeRequest[generate-id() = generate-id(key('kTXLifeRequest',concat(ns:FundCode,'#',ns:AccountNumber))[1])]" />
</xsl:call-template>
</GrandTotal>
</xsl:copy>
</xsl:template>
<xsl:template name="totalSum">
<xsl:param name="groups" />
<xsl:param name="gpos" select="1"/>
<xsl:param name="sum" select="0" />
<xsl:choose>
<xsl:when test="$gpos <= count($groups)" >
<xsl:variable name="group"
select="key('kTXLifeRequest',concat($groups[$gpos]/ns:FundCode,'#',$groups[$gpos]/ns:AccountNumber))" />
<xsl:for-each select= "$group" >
<xsl:sort select="ns:TotalAmount" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:variable name="actTotal" select="ns:TotalAmount - sum($group/ns:TotalAmount)+ ns:TotalAmount" />
<xsl:call-template name="totalSum">
<xsl:with-param name="groups" select="$groups" />
<xsl:with-param name ="gpos" select="$gpos + 1" />
<xsl:with-param name="sum" select="$sum + $actTotal" />
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$sum"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
这是您对这些值求和的解决方案:
XSLT:<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="Request" match="ns:TXLifeRequest" use="ns:FundCode"/>
<xsl:template match="ns:TXLife">
<TXLife>
<xsl:variable name="result"><xsl:apply-templates
select="ns:TXLifeRequest[generate-id() = generate-id(key('Request',ns:FundCode))]"/>
</xsl:variable>
<xsl:copy-of select="$result"/>
<TXLifeRequest><xsl:element name="GrandTotal"><xsl:value-of select="sum($result//TotalAmount)"/></xsl:element></TXLifeRequest>
</TXLife>
</xsl:template>
<xsl:template match="ns:TXLifeRequest">
<TXLifeRequest>
<xsl:for-each select="*">
<xsl:choose>
<xsl:when test="name()='TotalAmount'">
<xsl:variable name="currentFundCode" select="preceding-sibling::ns:FundCode"/>
<xsl:variable name="currentAccountNumber" select="preceding-sibling::ns:AccountNumber"/>
<xsl:variable name="amountToBeDeduct"
select="parent::ns:TXLifeRequest/following-sibling::ns:TXLifeRequest[ns:FundCode=$currentFundCode and ns:AccountNumber=$currentAccountNumber]/ns:TotalAmount/text()"/>
<xsl:variable name="actualAmt" select=". - $amountToBeDeduct"/>
<xsl:element name="{name()}">
<xsl:choose>
<xsl:when test="starts-with($actualAmt,'-')">
<xsl:value-of select="substring-after($actualAmt,'-')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$actualAmt"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</TXLifeRequest>
</xsl:template>
</xsl:stylesheet>
输出:<TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">
<TXLifeRequest>
<FundCode>LTRW00</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Cr</ReversalInd>
<TotalAmount>1250</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<FundCode>LUL500</FundCode>
<AccountNumber>34142</AccountNumber>
<ReversalInd>Cr</ReversalInd>
<TotalAmount>300</TotalAmount>
</TXLifeRequest>
<TXLifeRequest>
<GrandTotal>1550</GrandTotal>
</TXLifeRequest>
</TXLife>