Search code examples
xsltxslt-1.0muenchian-grouping

How to properly use the Muenchian for grouping a very repetitive tag by an element?


I am facing an issue using the Muenchian. I have a very large xml to transform into a new output. I've build the xsl to have a key using an element as the "parent" to group by, and everything to return as child. The source has many times the same Parent for different child, but it brings only the 1st one.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <Calculate_Account_Level_S6>

<Account_Number_ANI_ID17>7700.401100.900</Account_Number_ANI_ID17>
 <Description001_ID19>A/P ThirdParty</Description001_ID19>
 <Parent_Account_Number_ANI_ID21>401100.900</Parent_Account_Number_ANI_ID21>
 <DebitCreditAccount_ID26>A</DebitCreditAccount_ID26>
 <Account_Group_Gen_ID28>MX2010101</Account_Group_Gen_ID28>
</Calculate_Account_Level_S6>

<Calculate_Account_Level_S6>
 <Account_Number_ANI_ID17>7700100.401100.900</Account_Number_ANI_ID17>
 <Description001_ID19>A/P ThirdParty</Description001_ID19>
 <Parent_Account_Number_ANI_ID21>401100.900</Parent_Account_Number_ANI_ID21>
 <DebitCreditAccount_ID26>A</DebitCreditAccount_ID26>
 <Account_Group_Gen_ID28>MX2010101</Account_Group_Gen_ID28>
</Calculate_Account_Level_S6>
 <Calculate_Account_Level_S6>
 <Account_Number_ANI_ID17>7700101.401100.900</Account_Number_ANI_ID17>
 <Description001_ID19>A/P ThirdParty</Description001_ID19>
 <Parent_Account_Number_ANI_ID21>401100.900</Parent_Account_Number_ANI_ID21>
 <DebitCreditAccount_ID26>A</DebitCreditAccount_ID26>
 <Account_Group_Gen_ID28>MX2010101</Account_Group_Gen_ID28>
</Calculate_Account_Level_S6>

 XSL KEY:
 <xsl:key name="GrpParentAccount" match="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6" use="Parent_Account_Number_ANI_ID21" />
 <xsl:key name="Account" match="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6" use="Account_Number_ANI_ID17" />
 Coding:
   <xsl:for-each select="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6[count(. | key('GrpParentAccount', Parent_Account_Number_ANI_ID21)[1]) = 1]">
    <xsl:sort select="Parent_Account_Number_ANI_ID21"/>
    <xsl:sort select="Account_Number_ANI_ID17"/>
      <catalogocuentas:Ctas>
        <xsl:attribute name="CodAgrup">
          <xsl:value-of select="substring(Account_Group_Gen_ID28,3.0,3.0)"/>
        </xsl:attribute>
        <xsl:attribute name="NumCta">
          <xsl:value-of select="Parent_Account_Number_ANI_ID21"/>
        </xsl:attribute>
        <xsl:attribute name="Desc">
          <xsl:value-of select="Converted_Account_Description_ID29"/>
        </xsl:attribute>
          <xsl:attribute name="SubCtaDe">
            <xsl:text disable-output-escaping="no"></xsl:text>
          </xsl:attribute>
        <xsl:attribute name="Nivel">
          <xsl:text disable-output-escaping="no">1</xsl:text>
        </xsl:attribute>
        <xsl:attribute name="Natur">
          <xsl:value-of select="DebitCreditAccount_ID26"/>
        </xsl:attribute>
      </catalogocuentas:Ctas>
    <!-- Grouping End -->

       <!-- Printing All Accounts by Group -->
       <xsl:for-each select="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6[count(. | key('Account', Account_Number_ANI_ID17)[1]) = 1]">-->
        <catalogocuentas:Ctas>
         <xsl:attribute name="CodAgrup">
           <xsl:value-of select="substring(Account_Group_Gen_ID28,3.0,5.0)"/>
         </xsl:attribute>
        <xsl:attribute name="NumCta">
          <xsl:value-of select="Account_Number_ANI_ID17"/>
        </xsl:attribute>
        <xsl:attribute name="Desc">
          <xsl:value-of select="Converted_Account_Description_ID29"/>
        </xsl:attribute>
        <xsl:if test='Parent_Account_Number_ANI_ID21 != ""'>
          <xsl:attribute name="SubCtaDe">
            <xsl:value-of select="Parent_Account_Number_ANI_ID21"/>
          </xsl:attribute>
        </xsl:if>
        <xsl:attribute name="Nivel">
          <xsl:text disable-output-escaping="no">2</xsl:text>
        </xsl:attribute>
        <xsl:attribute name="Natur">
          <xsl:value-of select="DebitCreditAccount_ID26"/>
        </xsl:attribute>
      </catalogocuentas:Ctas>
  </xsl:for-each>
  </xsl:for-each>
</catalogocuentas:Catalogo>
<catalogocuentas:Ctas CodAgrup="201" NumCta="401100.900" Desc="Proveedores IVA 16%" SubCtaDe="" Nivel="1" Natur="A"/><catalogocuentas:Ctas CodAgrup="20101" NumCta="7700.401100.900" Desc="Proveedores IVA 16%" SubCtaDe="401100.900" Nivel="2" Natur="A"/></catalogocuentas:Catalogo>
 I was expecting to print all Calculate_Account_Level_S6/Account_Number_ANI_ID17 by the Calculate_Account_Level_S6/Parent_Account_Number_ANI_ID21 Any help is very WELCOME !!! :)

Solution

  • Try changing the second key from

    <xsl:key name="Account" match="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6" use="Account_Number_ANI_ID17" />
    

    to

    <xsl:key name="Account" match="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6" use="concat(Account_Number_ANI_ID17, '|', Account_Number_ANI_ID17)" />
    

    and the inner for-each from

    <xsl:for-each select="/RLA70901/Generic_Char_of_Account_Generation_S5/Calculate_Account_Level_S6[count(. | key('Account', Account_Number_ANI_ID17)[1]) = 1]">
    

    to

    <xsl:for-each select="key('GrpParentAccount', Parent_Account_Number_ANI_ID21)[count(. | key('Account', concat(Account_Number_ANI_ID17, '|', Account_Number_ANI_ID17))[1]) = 1]">