Hi,
Hi Geert,
Thanks a lot for pointing the bug.. I was infact
testing my stylesheet again, and was getting
StackOverFlow error. And your mail pointed the bug..
Thanks for saving my time!
I was actually considering whether the node-set could be eliminated or not. My first impression was:
easily, but then I noticed you used the keys on the document fragment. Which is actually quite nice.
Can anyone tell me how that fits into the XSLT 1 recommendation?
By the way, I realize that it opens an alternative to the node-set function! Wrap your fragment in
some obscure element name (or just use some namespace) and add a key that only matches that element.
Should work, I guess..
I suggest, please post your XSL. It'll help the
original poster.
Very true, here it comes:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt">
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:key name="folders" match="folder" use="@path" />
<xsl:template match="root">
<xsl:variable name="folders">
<!-- create a temporary tree with a folder structure -->
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:for-each select="file">
<!-- sort the files for nicer output -->
<xsl:sort select="@path" />
<xsl:sort select="@name" />
<!-- build a folder structure for each file (separately) -->
<xsl:apply-templates select="." mode="build-folders">
<xsl:with-param name="path" select="concat(@path, @name)" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:variable>
<!-- we have files in separate folder elements, now merge them -->
<xsl:apply-templates select="exslt:node-set($folders)/node()" mode="merge"
/>
</xsl:template>
<xsl:template match="file" mode="build-folders">
<xsl:param name="path-base" />
<xsl:param name="path" /> <!-- assumption: path always starts with '/' -->
<!-- folder-count equals the number of slashes in the path, minus one for the
file name -->
<xsl:param name="folder-count" select="string-length($path) - string-length(translate($path,
'/', '')) - 1"/>
<xsl:choose>
<!-- should not occur, actually -->
<xsl:when test="string-length($path) = 0" />
<!-- path contains slashes, output a folder -->
<xsl:when test="$folder-count > 0">
<!-- Note: folder-count = 1 means at least two slashes -->
<xsl:variable name="folder-name"
select="substring-before(substring-after($path, '/'), '/')" />
<xsl:variable name="folder-path" select="concat($path-base, '/',
$folder-name)" />
<xsl:variable name="remainder" select="substring-after(substring-after($path,
'/'), '/')" />
<folder name="{$folder-name}" path="{$folder-path}">
<!-- and recurse to add sub folders -->
<xsl:apply-templates select="." mode="build-folders">
<xsl:with-param name="path" select="concat('/', $remainder)" />
<xsl:with-param name="path-base" select="$folder-path" />
</xsl:apply-templates>
</folder>
</xsl:when>
<!-- no more slashes, output the file -->
<xsl:otherwise>
<!-- note: could do a xsl:copy-of select="." as well -->
<file name="{(_at_)name}" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="root" mode="merge">
<xsl:copy>
<xsl:copy-of select="@*" />
<!-- insert top-level files -->
<xsl:copy-of select="file" />
<!-- apply those folders that are the first ones with a specific path -->
<xsl:apply-templates select="folder[generate-id(.) = generate-id(key('folders', @path)[1])]"
mode="merge"/>
</xsl:copy>
</xsl:template>
<xsl:template match="folder" mode="merge">
<xsl:copy>
<!-- note: one might want to suppress the path attribute -->
<xsl:copy-of select="@*" />
<xsl:copy-of select="key('folders', @path)/file" />
<xsl:apply-templates select="key('folders', @path)/folder[generate-id(.) =
generate-id(key('folders', @path)[1])]" mode="merge"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--