[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: most efficient flat file listing to hierarchical

Subject: Re: most efficient flat file listing to hierarchical
From: James Fuller <jim.fuller@xxxxxxxxxxxxxx>
Date: Thu, 11 Jan 2007 17:38:51 +0100
Re:  most efficient flat file listing to hierarchical
Dimitre Novatchev wrote:

this is an elegant template, really shows the power and sweetspot hit by
XSLT 2.0 (anyone doing this in XSLT 1.0, barring FXSL, this becomes a
bit of a nightmare)....any alternate approaches which makes things more
efficient (i dont think its possible to optimise the MKay recursive
approach).


Why bar FXSL -- are we masochistic? :oO)


DavidC's approach was an eye opener....my XSLT 1.0 approach was more along the lines of Mukul's.

FXSL sometimes gets tagged with a 'hard to understand' tags...though your approach illustrates that this is not the case

Here's my take on this problem. Trying to adhere to the KISS
principle, I'm using a two-step approach naturally expressed as
functional composition.

Notice that not only is this a litlle easier to understand, but that
the main "powerhorse" (the function f:makeTree() ) is just 17 lines of
code:


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://fxsl.sf.net/" exclude-result-prefixes="f xs">

<xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:template match="/*">
   <xsl:sequence select="f:makeTree(f:tokenizePaths(/*/*), 1)"/>
 </xsl:template>

 <xsl:function name="f:tokenizePaths">
   <xsl:param name="pfilePaths" as="element()+"/>
   <xsl:for-each select="$pfilePaths">
      <item>
         <xsl:for-each select="tokenize(.,'/')">
            <q><xsl:value-of select="."/></q>
         </xsl:for-each>
      </item>
   </xsl:for-each>
 </xsl:function>

 <xsl:function name="f:makeTree" as="element()*">
   <xsl:param name="pItems" as="element()*"/>
   <xsl:param name="pqLevel" as="xs:integer"/>

<xsl:for-each-group select="$pItems" group-by="q[$pqLevel]">
<xsl:choose>
<xsl:when test="count(current-group()) = 1">
<file name="{q[$pqLevel]}"/>
</xsl:when>
<xsl:otherwise>
<dir name="{q[$pqLevel]}">
<xsl:sequence select="f:makeTree(current-group(), $pqLevel+1)"/>
</dir>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
</xsl:stylesheet>


very nice...and extremely readable.

thx for everyone spending such quality 'cycles' on this problem, this problem's answers really impresses me how much quality in depth and approach exists on this list...very much appreciated.

cheers, Jim

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.