Re: [xsl] group by tags

Subject: Re: [xsl] group by tags
From: Dave Pawson <davep@xxxxxxxxxxxxx>
Date: Wed, 02 Jul 2008 11:29:49 +0100
Michael Kay wrote:
A bit tricky, this one!

I think I would tackle it by first flattening the structure into something
like this:

<Book rdf:ID="boo2">
   <address rdf:dataytpe="aaa" path="">Almogavers 56</address>
   <month rdf:dataytpe="bbb" path="event/Inbook">July</month>
   <year rdf:dataytpe="ccc" path="event/Inbook">2006</year>
   <year rdf:dataytpe="ddd" path="proceedings/Proceedings">2008</year>
   <month rdf:dataytpe="ddd" path="proceedings/Proceedings">May</month>

etc.

That part can be done by

<xsl:for-each select="//*[not(*)]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:attribute name="path" select="string-join(ancestor::*/name(),
'/')"/>
  </xsl:copy>
</xsl:for-each>

Then you can construct the output with

<xsl:for-each-group select="*" group-by="@path">
  <xsl:sequence select="f:nest(tokenize(@path, '/'), current-group())"/>
</xsl:for-each>

using the recursive function

<xsl:function name="f:nest" as="element()*">
  <xsl:param name="path" as="xs:string*"/>
  <xsl:param name="content" as="element()*"/>
  <xsl:choose>
    <xsl:when test="exists($path)">
      <xsl:element name="{$path[1]}">
         <xsl:sequence select="f:nest(remove($path, 1), $content)"/>
      </xsl:element>
    </xsl:when>
    <xsl:otherwise>
       <xsl:sequence select="$content"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

Not tested. Needs refinement if namespaces are involved.


<xsl:variable name='flattened'>
<xsl:for-each select="//*[not(*)]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="path" select="string-join(ancestor::*[not(position() = last())]/name(),
'/')"/>
</xsl:copy>
</xsl:for-each>
</xsl:variable>


<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";>

<xsl:for-each-group select="$flattened/*" group-by="@path">
<xsl:sequence select="f:nest(tokenize(@path, '/'), current-group())"/>
</xsl:for-each-group>
</rdf:RDF>


Neat Michael.

regards


regards


--
Dave Pawson
XSLT XSL-FO FAQ.
http://www.dpawson.co.uk

Current Thread