开发者

Concatenate duplicate elements information based on multiple elements using XSL

开发者 https://www.devze.com 2023-03-22 06:01 出处:网络
I am not that bright in XSL. I have an XML as below: <?xml version=\"1.0\" ?> <accountitem>

I am not that bright in XSL. I have an XML as below:

<?xml version="1.0" ?>
    <accountitem>
         <Entry_Date>2011-06-24T00:00:00-05:00</Entry_Date>
         <Contract>4570000010</Contract>
         <Account>0</Account>
         <general_desc>Systematic Withdrawal</general_desc>
         <net>1108.3700</net>
         <gross>1108.3700</gross>
         <Person_Name>WHITEY HOUSE</Person_Name>
         <Last_Name>HOUSE</Last_Name>
         <agent_name>BROWN, JACK</agent_name>
         <Legal_Verb>N</Legal_Verb>
         <Payeename>NONE</Payeename>
         <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
         <Entry_Date>2011-06-24T00:00:00-05:00</Entry_Date>
         <Contract>4570000010</Contract>
         <Account>0</Account>
         <general_desc>Systematic Withdrawal</general_desc>
         <net>1108.3700</net>
         <gross>1196.5400</gross>
         <Person_Name>WHITEY HOUSE</Person_Name>
         <Last_Name>HOUSE</Last_Name>
         <agent_name>BROWN, JACK</agent_name>
         <Legal_Verb>N</Legal_Verb>
         <Payeename>NONE</Payeename>
         <Closed_Flag>0</Closed_Flag>       
    </accountitem>
    <accountitem>
         <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
         <Contract>4570000009</Contract>
         <Account>0</Account>
         <general_desc>Systematic Withdrawal</general_desc>
         <net>798.4038</net>
         <gross>901.5600</gross>
         <Person_Name>WHITEY HOUSE</Person_Name>
         <Last_Name>HOUSE</Last_Name>
         <agent_name>BROWN, JACK</agent_name>
         <Legal_Verb>N</Legal_Verb>
         <Payeename>NONE</Payeename>
         <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
         <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
         <Contract>4570000009</Contract>
         <Account>0</Account>
         <general_desc>Systematic Withdrawal</general_desc>
         <net>798.4038</net>
         <gross>901.5600</gross>
         <Person_Name>WHITEY HOUSE</Person_Name>
         <Last_Name>HOUSE</Last_Name>
         <agent_name>DUCK, DONALD Q</agent_name>
         <Legal_Verb>N</Legal_Verb>
         <Payeename>NONE</Payeename>
         <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
         <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
         <Contract>4570000009</Contract>
         <Account>0</Account>
         <general_desc>Systematic Withdrawal</general_desc>
         <net>800.3800</net>
         <gross>820.3400</gross>
         <Person_Name>WHITEY HOUSE</Person_Name>
         <Last_Name>HOUSE</Last_Name>
         <agent_name>BROWN, JACK</agent_name>
         <Legal_Verb>N</Legal_Verb>
         <Payeename>NONE</Payeename>
         <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
         <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
         <Contract>4570000009</Contract>
         <Account>0</Account>
         <general_desc>Systemat开发者_开发百科ic Withdrawal</general_desc>
         <net>800.3800</net>
         <gross>820.3400</gross>
         <Person_Name>WHITEY HOUSE</Person_Name>
         <Last_Name>HOUSE</Last_Name>
         <agent_name>DUCK, DONALD Q</agent_name>
         <Legal_Verb>N</Legal_Verb>
         <Payeename>NONE</Payeename>
         <Closed_Flag>0</Closed_Flag>
    </accountitem>

I want it to be converted it as below:

 <?xml version="1.0" ?>
 <accountitem>
    <Entry_Date>2011-06-24T00:00:00-05:00</Entry_Date>
    <Contract>4570000010</Contract>
    <Account>0</Account>
    <general_desc>Systematic Withdrawal</general_desc>
    <net>1108.3700</net>
    <gross>1108.3700</gross>
    <Person_Name>WHITEY HOUSE</Person_Name>
    <Last_Name>HOUSE</Last_Name>
    <agent_name>BROWN, JACK</agent_name>
    <Legal_Verb>N</Legal_Verb>
    <Payeename>NONE</Payeename>
    <Closed_Flag>0</Closed_Flag>
 </accountitem>
 <accountitem>
    <Entry_Date>2011-06-24T00:00:00-05:00</Entry_Date>
    <Contract>4570000010</Contract>
    <Account>0</Account>
    <general_desc>Systematic Withdrawal</general_desc>
    <net>1108.3700</net>
    <gross>1196.5400</gross>
    <Person_Name>WHITEY HOUSE</Person_Name>
    <Last_Name>HOUSE</Last_Name>
    <agent_name>BROWN, JACK</agent_name>
    <Legal_Verb>N</Legal_Verb>
    <Payeename>NONE</Payeename>
    <Closed_Flag>0</Closed_Flag>
 </accountitem>
 <accountitem>
    <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
    <Contract>4570000009</Contract>
    <Account>0</Account>
    <general_desc>Systematic Withdrawal</general_desc>
    <net>798.4038</net>
    <gross>901.5600</gross>
    <Person_Name>WHITEY HOUSE</Person_Name>
    <Last_Name>HOUSE</Last_Name>
    <agent_name>BROWN, JACK; DUCK, DONALD Q</agent_name>
    <Legal_Verb>N</Legal_Verb>
    <Payeename>NONE</Payeename>
    <Closed_Flag>0</Closed_Flag>
 </accountitem>
 <accountitem>
    <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
    <Contract>4570000009</Contract>
    <Account>0</Account>
    <general_desc>Systematic Withdrawal</general_desc>
    <net>800.3800</net>
    <gross>820.3400</gross>
    <Person_Name>WHITEY HOUSE</Person_Name>
    <Last_Name>HOUSE</Last_Name>
    <agent_name>BROWN, JACK; DUCK, DONALD Q</agent_name>
    <Legal_Verb>N</Legal_Verb>
    <Payeename>NONE</Payeename>
    <Closed_Flag>0</Closed_Flag>
 </accountitem>

or in short, I want the agent_name to be concatenated based on contract, account, net, gross combination.

My current XSL is like below:

           <?xml version="1.0" ?>
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:key name="kContractAccountNetGross" match="accountitem" use="concat(contract,account,format-number(net, '$#,###.00'),format-number(gross, '$#,###.00'))"/>

      <xsl:template match="accountitem">
      <xsl:variable name="agentInfo">
       <xsl:choose>
         <xsl:when test="count(key('kContractAccountNetGross',concat(contract,account,format-number(net, '$#,###.00'),format-number(gross, '$#,###.00')))) > 1">
           <xsl:value-of select="concat(agent_name,';',accountitem/agent_name)"/>
         </xsl:when>
         <xsl:otherwise>
           <xsl:value-of select="agent_name"/>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:variable>
     <xsl:choose>
       <xsl:when test="count(key('kContractAccountNetGross',concat(contract,account,format-number(net, '$#,###.00'),format-number(gross, '$#,###.00')))) = 1">
         <tr>
           <xsl:attribute name="class">
             <xsl:choose>
               <xsl:when test="position() mod 2=0">
                 <xsl:text>altItem     </xsl:text>
               </xsl:when>
               <xsl:otherwise>
                 <xsl:text>item     </xsl:text>
               </xsl:otherwise>
             </xsl:choose>
           </xsl:attribute>
           <xsl:attribute name="onmouseover">
             <xsl:text>this.className='mouseover'     </xsl:text>
           </xsl:attribute>
           <xsl:attribute name="onmouseout">
             <xsl:choose>
               <xsl:when test="position() mod 2=0">
                 <xsl:text>this.className='altItem'     </xsl:text>
               </xsl:when>
               <xsl:otherwise>
                 <xsl:text>this.className='item'     </xsl:text>
               </xsl:otherwise>
             </xsl:choose>
           </xsl:attribute>
           <xsl:attribute name="rowid">
             <xsl:value-of select="position()"/>
           </xsl:attribute>
           <td class="date">
             <xsl:attribute name="colName">
               <xsl:text>date     </xsl:text>
             </xsl:attribute>
             <xsl:value-of select="concat(substring(Entry_Date,6,2),'/', substring(Entry_Date,9,2), '/',substring(Entry_Date,1,4))" />
           </td>
           <td class="contract">
             <xsl:attribute name="colName">
               <xsl:text>contract     </xsl:text>
             </xsl:attribute>
             <xsl:choose>
               <xsl:when test="Closed_Flag = 1">
                 <xsl:value-of select="Contract"/>
               </xsl:when>
               <xsl:otherwise>
                 <a>
                   <xsl:attribute name="href">
                     <xsl:text>?hash=1&amp;contract=     </xsl:text>
                     <xsl:value-of select="Contract"/>
                     <xsl:text>&amp;account=     </xsl:text>
                     <xsl:value-of select="Account"/>
                   </xsl:attribute>
                   <xsl:value-of select="Contract"/>
                 </a>
               </xsl:otherwise>
             </xsl:choose>

           </td>
           <td class="account" colName="account">
             <xsl:if test="not($showAccount)">
               <xsl:attribute name="style">display:none     </xsl:attribute>
             </xsl:if>
             <xsl:if test="Account!=0">
               <xsl:value-of select='Account'/>
             </xsl:if>
           </td>
           <td class="tblOwner">
             <xsl:attribute name="colName">
               <xsl:text>owner     </xsl:text>
             </xsl:attribute>
             <xsl:value-of select='Person_Name'/>
           </td>
           <td class="tblOwner">
             <xsl:attribute name="colName">
               <xsl:text>Financial Advisor     </xsl:text>
             </xsl:attribute>
             <xsl:value-of select='$agentInfo'/>
           </td>
           <td class="general_desc">
             <xsl:attribute name="colName">
               <xsl:text>general_desc     </xsl:text>
             </xsl:attribute>
             <xsl:value-of select='general_desc'/>
           </td>
           <td align="right" class="value">
             <xsl:attribute name="colName">
               <xsl:text>net     </xsl:text>
             </xsl:attribute>
             <xsl:value-of select="format-number(net, '$#,###.00')"/>
           </td>
           <td align="right" class="value">
             <xsl:attribute name="colName">
               <xsl:text>gross     </xsl:text>
             </xsl:attribute>
             <xsl:value-of select="format-number(gross, '$#,###.00')"/>
           </td>
           <xsl:if test="Payeename!='NONE'">
             <td class="general_desc">
               <xsl:attribute name="colName">
                 <xsl:text>Payeename     </xsl:text>
               </xsl:attribute>
               <xsl:value-of select='Payeename'/>
             </td>
           </xsl:if>
         </tr>
       </xsl:when>
     </xsl:choose>
   </xsl:template>
 </xsl:stylesheet>

I selected only the XSL section applicable for the transformation. Any thoughts?


This is just an example to show you how to do what you want. The main point here is application of Meunchian method to perform grouping. I've minimized in the transform the produced output so that you can easily see that the wanted result is obtained.

NOTE XML is case sensitive. Your current key is not built properly.

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>

    <xsl:key name="k-accounts" match="accountitem" 
        use="concat(Contract,Account,format-number(net, '$#,###.00'),format-number(gross, '$#,###.00'))"/>

    <xsl:template match="so">
        <xsl:apply-templates select="accountitem
            [generate-id()
            = generate-id(key('k-accounts', concat(Contract,Account,format-number(net, '$#,###.00'),format-number(gross, '$#,###.00')))
            [1])]"/>
    </xsl:template>

    <xsl:template match="accountitem">
        <xsl:copy>
            <xsl:copy-of select="Contract|Account|net|gross"/>
            <agent_name>
                <xsl:value-of select="agent_name"/>
                <xsl:apply-templates select="key('k-accounts',
                    concat(Contract,Account,format-number(net, '$#,###.00'),format-number(gross, '$#,###.00')))/agent_name
                    [.!=current()/agent_name]"
                    mode="agent_name"/>
            </agent_name>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="agent_name" mode="agent_name">
        <xsl:value-of select="concat('; ',.)"/>
    </xsl:template>

</xsl:stylesheet>

Given this input (slightly modified to make it well formed):

<so>
    <accountitem>
        <Entry_Date>2011-06-24T00:00:00-05:00</Entry_Date>
        <Contract>4570000010</Contract>
        <Account>0</Account>
        <general_desc>Systematic Withdrawal</general_desc>
        <net>1108.3700</net>
        <gross>1108.3700</gross>
        <Person_Name>WHITEY HOUSE</Person_Name>
        <Last_Name>HOUSE</Last_Name>
        <agent_name>BROWN, JACK</agent_name>
        <Legal_Verb>N</Legal_Verb>
        <Payeename>NONE</Payeename>
        <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
        <Entry_Date>2011-06-24T00:00:00-05:00</Entry_Date>
        <Contract>4570000010</Contract>
        <Account>0</Account>
        <general_desc>Systematic Withdrawal</general_desc>
        <net>1108.3700</net>
        <gross>1196.5400</gross>
        <Person_Name>WHITEY HOUSE</Person_Name>
        <Last_Name>HOUSE</Last_Name>
        <agent_name>BROWN, JACK</agent_name>
        <Legal_Verb>N</Legal_Verb>
        <Payeename>NONE</Payeename>
        <Closed_Flag>0</Closed_Flag>       
    </accountitem>
    <accountitem>
        <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
        <Contract>4570000009</Contract>
        <Account>0</Account>
        <general_desc>Systematic Withdrawal</general_desc>
        <net>798.4038</net>
        <gross>901.5600</gross>
        <Person_Name>WHITEY HOUSE</Person_Name>
        <Last_Name>HOUSE</Last_Name>
        <agent_name>BROWN, JACK</agent_name>
        <Legal_Verb>N</Legal_Verb>
        <Payeename>NONE</Payeename>
        <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
        <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
        <Contract>4570000009</Contract>
        <Account>0</Account>
        <general_desc>Systematic Withdrawal</general_desc>
        <net>798.4038</net>
        <gross>901.5600</gross>
        <Person_Name>WHITEY HOUSE</Person_Name>
        <Last_Name>HOUSE</Last_Name>
        <agent_name>DUCK, DONALD Q</agent_name>
        <Legal_Verb>N</Legal_Verb>
        <Payeename>NONE</Payeename>
        <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
        <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
        <Contract>4570000009</Contract>
        <Account>0</Account>
        <general_desc>Systematic Withdrawal</general_desc>
        <net>800.3800</net>
        <gross>820.3400</gross>
        <Person_Name>WHITEY HOUSE</Person_Name>
        <Last_Name>HOUSE</Last_Name>
        <agent_name>BROWN, JACK</agent_name>
        <Legal_Verb>N</Legal_Verb>
        <Payeename>NONE</Payeename>
        <Closed_Flag>0</Closed_Flag>
    </accountitem>
    <accountitem>
        <Entry_Date>2011-06-20T00:00:00-05:00</Entry_Date>
        <Contract>4570000009</Contract>
        <Account>0</Account>
        <general_desc>Systematic Withdrawal</general_desc>
        <net>800.3800</net>
        <gross>820.3400</gross>
        <Person_Name>WHITEY HOUSE</Person_Name>
        <Last_Name>HOUSE</Last_Name>
        <agent_name>DUCK, DONALD Q</agent_name>
        <Legal_Verb>N</Legal_Verb>
        <Payeename>NONE</Payeename>
        <Closed_Flag>0</Closed_Flag>
    </accountitem>
</so>

The following output (minimized to show that correct results are achieved) is obtained:

<accountitem>
   <Contract>4570000010</Contract>
   <Account>0</Account>
   <net>1108.3700</net>
   <gross>1108.3700</gross>
   <agent_name>BROWN, JACK</agent_name>
</accountitem>
<accountitem>
   <Contract>4570000010</Contract>
   <Account>0</Account>
   <net>1108.3700</net>
   <gross>1196.5400</gross>
   <agent_name>BROWN, JACK</agent_name>
</accountitem>
<accountitem>
   <Contract>4570000009</Contract>
   <Account>0</Account>
   <net>798.4038</net>
   <gross>901.5600</gross>
   <agent_name>BROWN, JACK; DUCK, DONALD Q</agent_name>
</accountitem>
<accountitem>
   <Contract>4570000009</Contract>
   <Account>0</Account>
   <net>800.3800</net>
   <gross>820.3400</gross>
   <agent_name>BROWN, JACK; DUCK, DONALD Q</agent_name>
</accountitem>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号