我有一个要求,我需要根据不同部分中的两个不同的值显示差异量(<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>
相同。
现在<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>
此外,如果您发现应根据最高TotalAmount值识别CR {DR <ReversalInd>
。
我已经应用了下面的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>
答案 0 :(得分:1)
这是将这些值相加的解决方案:
<强> 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>
答案 1 :(得分:1)
根据 Muenchian分组尝试以下解决方案。 TXLifeRequest按FundCode和AccountNumber分组。
即使组中有两个以上的条目,也会大喊大叫。组输出的所有数据(特别是ReversalInd)来自具有最高TotalAmount的数据。 TotalAmount的值是第一个(最高)TotalAmount和剩余的TotalAmount之差。
它还考虑了这个要求: &#34;如果您发现CR / DR应该根据最高的TotalAmount值进行识别。&#34;
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>