Below is a XSLT 1.0 solution. I have used the node-set
extension function..
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt">
<xsl:output method="xml" indent="yes" />
<xsl:key name="x" match="file" use="@parentfolder" />
<xsl:key name="y" match="file" use="concat(@folder,
'', @parentfolder)" />
<xsl:template match="/">
<xsl:variable name="RTF">
<temp>
<xsl:for-each select="root/file">
<xsl:variable name="folder-name">
<xsl:call-template name="get-folder-name">
<xsl:with-param name="path" select="@path"
/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="parent-folder-name">
<xsl:call-template
name="get-parent-folder-name">
<xsl:with-param name="path" select="@path"
/>
</xsl:call-template>
</xsl:variable>
<file name="{(_at_)name}" folder="{$folder-name}"
parentfolder="{$parent-folder-name}" />
</xsl:for-each>
</temp>
</xsl:variable>
<root>
<xsl:apply-templates
select="exslt:node-set($RTF)/temp" />
</root>
</xsl:template>
<xsl:template name="get-folder-name">
<xsl:param name="path" />
<xsl:choose>
<xsl:when test="(string-length($path) -
string-length(translate($path, '/', ''))) = 2">
<xsl:value-of
select="substring-before(substring-after($path, '/'),
'/')" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="get-folder-name">
<xsl:with-param name="path"
select="substring-after(@path, '/')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="get-parent-folder-name">
<xsl:param name="path" />
<xsl:choose>
<xsl:when test="(string-length($path) -
string-length(translate($path, '/', ''))) = 2">
<xsl:value-of select="substring-before($path,
'/')" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template
name="get-parent-folder-name">
<xsl:with-param name="path"
select="substring-after(@path, '/')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="temp">
<xsl:apply-templates select="file[generate-id(.) =
generate-id(key('x', @parentfolder)[1])]" />
</xsl:template>
<xsl:template match="file">
<xsl:if test="@parentfolder != ''">
<folder name="{(_at_)parentfolder}">
<xsl:for-each select="key('x',
@parentfolder)[generate-id(.) = generate-id(key('y',
concat(@folder, '', @parentfolder))[1])]">
<folder name="{(_at_)folder}">
<xsl:for-each select="key('y', concat(@folder,
'', @parentfolder))">
<file name="{(_at_)name}" />
</xsl:for-each>
</folder>
</xsl:for-each>
</folder>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When the above XSL is applied to XML -
<?xml version="1.0" encoding="UTF-8"?>
<root>
<file name ="f1.xyz" path="/test/"/>
<file name ="f2.xyz" path="/test/folderInFolder/"/>
<file name ="f3.xyz" path="/test/folderInFolder/"/>
<file name ="f4.xyz" path="/test/folderInFolder2/"/>
<file name ="f5.xyz"
path="/test2/folderInFolder3/"/>
</root>
it produces o/p -
<?xml version="1.0" encoding="UTF-8"?>
<root>
<folder name="test">
<folder name="folderInFolder">
<file name="f2.xyz"/>
<file name="f3.xyz"/>
</folder>
<folder name="folderInFolder2">
<file name="f4.xyz"/>
</folder>
</folder>
<folder name="test2">
<folder name="folderInFolder3">
<file name="f5.xyz"/>
</folder>
</folder>
</root>
Regards,
Mukul
--- Thomas Zöchling <thomas(_dot_)zoechling(_at_)gmx(_dot_)at> wrote:
Hi list!
Does someone know a method to create a nested xml
Tree structure from file
listing with paths?
eg.
...
<file name ="f1.xyz" path="/test/"/>
<file name ="f2.xyz" path="/test/folderInFolder/"/>
<file name ="f3.xyz" path="/test/folderInFolder/"/>
<file name ="f4.xyz" path="/test/folderInFolder2/"/>
<file name ="f5.xyz"
path="/test2/folderInFolder3/"/>
...
to
<folder name="test">
<folder name="folderInFolder">
<file name="f2.xyz"/>
<file name="f3.xyz"/>
</folder
<folder name="folderInFolder2">
<file name="f4.xyz"/>
</folder
<folder name ="test">
<folder name="folderInFolder3">
<file name="f5.xyz">
</folder>
</folder>
Maybe anyone solved a similar problem?
__________________________________
Do you Yahoo!?
Send holiday email and support a worthy cause. Do good.
http://celebrity.mail.yahoo.com
--~------------------------------------------------------------------
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>
--~--