xslt 比较两个不同的节点然后组合 [英] xslt compare two different nodes and then combine

查看:25
本文介绍了xslt 比较两个不同的节点然后组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要求,我需要根据不同部分中的两个不同值显示差异金额().输入 xml 如下.

I have a requirement where i need to show the difference amount (<TotalAmount>) based on two different values which is in different section.The input xml as below.

 <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 中,找出差异金额的标准是 .如果任何部分具有相同的 检索 并找出差异.

From the above xml the criteria to find difference amount is <FundCode> and <AccountNumber>. If any sections having same <FundCode> and <AccountNumber> retrieve <TotalAmount> and find the difference.

例如从上面的 xml:-

for example from above xml:-

有两个部分具有相同的 与 LTRW00 和 34142.现在 的差值是 1250 (1600 - 250).我也需要在其他部分重复这个逻辑.

There are two sections with the same <fundcode> and <Accountnumber> with LTRW00 and 34142. Now the difference of <TotalAmount> is 1250 (1600 - 250). I need to repeat this logic on other sections also.

所以最终输出的xml应该是这样的:

So the final output xml should like this:

 <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>

此外,如果您观察到 ,即 CR/DR 应根据最高的 TotalAmount 值进行识别.

And also if you observe the <ReversalInd> that is CR/DR should be identified based on highest TotalAmount value.

我已经应用了下面的 xslt 但没有输出.任何想法如何在 xslt 1.0 中实现.非常感谢.

I have applied the xslt below but no output. Any ideas how to implement in xslt 1.0. Greatly appreciated.

<?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() &gt; 1]"/>
        </xsl:variable>

        <xsl:if test="$val1 &gt; $val2">
            <remainingAmount><xsl:value-of select="$val1 - $val2"/></remainingAmount>
        </xsl:if>

    </xsl:template>
</xsl:stylesheet>

推荐答案

尝试以下基于 Muenchian 分组的解决方案.TXLifeRequest 按 FundCode 和 AccountNumber 分组.

Try following solution based on Muenchian grouping. The TXLifeRequest are grouped by FundCode and AccountNumber.

即使组中有两个以上的条目,它也会喊工作.一组输出(特别是 ReversalInd)的所有数据都来自具有最高 TotalAmount 的数据.TotalAmount 的值是第一个(最高)TotalAmount 与其余的差值.

It shout work even if there are more than two entries in the group. All Data for a group output (especial ReversalInd) is from the one with the highest TotalAmount. The value of TotalAmount is the difference of the first (highest) TotalAmount and the remaining ones.

它还考虑请求:此外,如果您观察到 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 &lt;= 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 比较两个不同的节点然后组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆