Объединить информацию о дубликатах элементов на основе нескольких элементов с использованием XSL - PullRequest
1 голос
/ 21 июля 2011

Я не такой яркий в XSL. У меня есть XML, как показано ниже:

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

Я хочу, чтобы оно было преобразовано, как показано ниже:

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

или, короче говоря, я хочу, чтобы имя агента было объединено на основе контракта, счета, нетто, валовой комбинации.

Мой текущий XSL, как показано ниже:

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

Я выбрал только секцию XSL, применимую для преобразования. Есть мысли?

1 Ответ

0 голосов
/ 22 июля 2011

Это просто пример, чтобы показать вам, как делать то, что вы хотите.Основным моментом здесь является применение метода Meunchian для выполнения группировки.Я преобразовал полученный результат в преобразование, чтобы вы могли легко увидеть, что желаемый результат получен.

ПРИМЕЧАНИЕ XML чувствителен к регистру .Ваш текущий key не построен должным образом.

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

Учитывая этот ввод (слегка измененный, чтобы сделать его правильно сформированным):

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

Следующий вывод (свернут, чтобы показать, что правильнорезультаты достигнуты) получается:

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