RE: [xsl] Can I group in three levels?

Subject: RE: [xsl] Can I group in three levels?
From: Jarno.Elovirta@xxxxxxxxx
Date: Thu, 7 Nov 2002 09:49:38 +0200
Hi,

> This is the XML to transform:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <ROWSET>
>    <ROW>
>       <ID>27835</ID>
>       <NUMBER>29715</NUMBER>
>       <PHONE>09876</PHONE>
>       <ACT>ACT34</ACT>
>    </ROW>
>    <ROW>
>       <ID>27835</ID>
>       <NUMBER>29716</NUMBER>
>       <PHONE>62784</PHONE>
>       <ACT>ACT87</ACT>
>    </ROW>
>    <ROW>
>       <ID>27835</ID>
>       <NUMBER>29716</NUMBER>
>       <PHONE>3333333</PHONE>
>       <ACT>ACT23</ACT>
>    </ROW>
>    <ROW>
>       <ID>27835</ID>
>       <NUMBER>29716</NUMBER>
>       <PHONE>3333333</PHONE>
>       <ACT>ACT111</ACT>
>    </ROW>
> </ROWSET>
> 
> 
> 
> First I want to group in a first level with the same 
> ID,NUMBER. Inside of 
> this first group, a second group with a second
> 
> group with PHONE. And finally a third group, inside the 
> second group with 
> ACT. I'm not sure if I'm explainig clear.

[snip]
 
> My desired output for the first XML is:
> 
> 
>   <?xml version="1.0" encoding="UTF-16" ?>
>   <ROOT xmlns:xalan="http://xml.apache.org/xslt";>
> 	  <ID>27835</ID>
> 	  <NUM>29715</NUM>
> 	  <PHONE_DATA>
> 		<PHONE>09876</PHONE>
> 		<ACT_DATA>
> 			<ACT>ACT34</ACT>
> 		</ACT_DATA>
> 	  </PHONE_DATA>
> 	  <ID>27835</ID>
> 	  <NUM>29716</NUM>
> 	  <PHONE_DATA>
> 		<PHONE>3333333</PHONE>
> 		<ACT_DATA>
> 			<ACT>ACT23</ACT>
> 		</ACT_DATA>
> 		<ACT_DATA>
> 			<ACT>ACT111</ACT>
> 		</ACT_DATA>
> 	  </PHONE_DATA>
> 	  <PHONE_DATA>
> 	  <PHONE>62784</PHONE>
> 			<ACT_DATA>ACT87</ACT_DATA>

Should this not be 

  <ACT_DATA>
    <ACT>ACT87</ACT>
  </ACT_DATA>

Like in the other ACT_DATA elements?

> 	   </PHONE_DATA>
>   </ROOT>

If the all ACT_DATA should contain ATC, then

  <xsl:key name="level1" match="ROW" use="concat(ID, ' ', NUMBER)"/>
  <xsl:key name="level2" match="ROW" use="concat(ID, ' ', NUMBER, ' ', PHONE)"/>
  <xsl:template match="ROWSET">
    <ROOT>
      <xsl:for-each select="ROW[generate-id(.) = generate-id(key('level1', concat(ID, ' ', NUMBER)))]">
        <xsl:sort select="ID"/>
        <xsl:copy-of select="ID"/>
        <NUM>
          <xsl:value-of select="NUMBER"/>
        </NUM>
        <xsl:variable name="group" select="concat(ID, ' ', NUMBER)"/>
        <xsl:for-each select="../ROW[generate-id(.) = generate-id(key('level2', concat(ID,' ',NUMBER, ' ', PHONE))) and concat(ID, ' ', NUMBER) = $group]">
          <xsl:sort select="PHONE"/>
          <PHONE_DATA>
            <xsl:copy-of select="PHONE"/>
            <xsl:for-each select="key('level2', concat(ID,' ',NUMBER, ' ', PHONE))/ACT">
              <ACT_DATA>
                <xsl:copy-of select="."/>
              </ACT_DATA>
            </xsl:for-each>
          </PHONE_DATA>
        </xsl:for-each>
      </xsl:for-each>
    </ROOT>
  </xsl:template>

Will get you there, but there are probably better solutions.

Cheers,

Jarno

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread