xsl-list
[Top] [All Lists]

Re: how to group nodes by id?

2002-12-02 10:05:39
--- Artur Matysiak  wrote:

 hi
 does anybody know how to convert the following XML:
 
 <elems>
 <elem id=1>
  <elem id=1/>
 </elem>
 <elem id=1>
  <elem id=2/>
 </elem>
 <elem id=2>
  <elem id=1/>
 </elem>
 <elem id=2>
  <elem id=2/>
 </elem>
 </elems>
 
 to the form
 
 <elems>
 <elem id=1>
  <elem id=1/>
  <elem id=2/>
 </elem>
 <elem id=2>
  <elem id=1/>
  <elem id=2/>
 </elem>
 </elems>
 
 thanks Artur


Hi Artur,

Here's a solution using the Muenchian method for grouping. Note that it
is used in a double-nested manner.

source.xml (corrected your original non-well-formed xml):
----------
<elems> 
  <elem id="1">  
    <elem id="1"/>  
    <elem id="2"/> </elem> 
  <elem id="1">  
    <elem id="2"/> </elem> 
  <elem id="1">  
    <elem id="3"/> </elem> 
  <elem id="2">  
    <elem id="1"/> </elem> 
  <elem id="2">  
    <elem id="2"/> </elem> 
</elems>

stylesheet:
----------
<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";> 
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
  
  <xsl:key name="kElem" match="elem[not(parent::elem)]" use="@id"/>
  <xsl:key name="kElem2" match="elem/elem" 
           use="concat(../@id, ':', @id)"/>
  
  <xsl:template match="/">
   <elems>
    <xsl:for-each select="//elem[generate-id()
                               = 
                                 generate-id(key('kElem',
                                                 @id)[1]
                                             )
                                 ]">
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        
        <xsl:for-each 
           select="//elem/elem[generate-id()
                       =
                        generate-id(key('kElem2',
                                         concat(current()/@id,
                                               ':',
                                               @id
                                               )
                                        )[1]
                                    )
                                  ]">
          <xsl:copy-of select="."/>
        </xsl:for-each>
      
      </xsl:copy>
    </xsl:for-each>
    </elems>
  </xsl:template>
</xsl:stylesheet>

Result:
------
<elems>
   <elem id="1">
      <elem id="1"/>
      <elem id="2"/>
      <elem id="3"/>
   </elem>
   <elem id="2">
      <elem id="1"/>
      <elem id="2"/>
   </elem>
</elems>


Hope this helped.



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

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



<Prev in Thread] Current Thread [Next in Thread>