RE: [xsl] Need to Transform a Flat XML Struture to a Hierarchical One

Subject: RE: [xsl] Need to Transform a Flat XML Struture to a Hierarchical One
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Thu, 27 Mar 2003 16:24:43 -0000
"Transforming a Flat XML Struture to a Hierarchical One" is the problem
usually called "grouping". Look up Muenchian grouping in your favourite
XSLT textbook or at http://www.jenitennison.com/xslt/grouping.

Michael Kay
Software AG
home: Michael.H.Kay@xxxxxxxxxxxx
work: Michael.Kay@xxxxxxxxxxxxxx 

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> Kuhn, Sam (Commerce Link)
> Sent: 27 March 2003 10:41
> To: 'XSL-List@xxxxxxxxxxxxxxxxxxxxxx'
> Cc: Kuhn, Sam (Commerce Link)
> Subject: [xsl] Need to Transform a Flat XML Struture to a 
> Hierarchical One
> 
> 
> I'm using TIBCO Business Works and unsure of the XSLT 
> processor.  I'm attempted to create a hierarchical XML 
> document containing nested elements from a flat document.
> 
> Source structure:
> 
> <rows>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0010</rec_nbr>
> 	<data>another chunk of data</data>
> </rows>
> <rows>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0020</rec_nbr>
> 	<data>another chunk of data</data>
> </rows>
> <rows>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0030</rec_nbr>
> 	<data>another chunk of data</data>
> </rows>
> <rows>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0040</rec_nbr>
> 	<data>another chunk of data</data>
> </rows>
> <rows>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0010</rec_nbr>
> 	<data>another chunk of data</data>
> </rows>
> <rows>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0020</rec_nbr>
> 	<data>another chunk of data</data>
> </rows>
> 
> ...
> 
> Desired Result Structure:
> 
> <0010>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0010</rec_nbr>
> 	<data>another chunk of data</data>
> </0010>
> <0020>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0020</rec_nbr>
> 	<data>another chunk of data</data>
> 	<0030>
> 		<prefix>chunk of data</prefix>
> 		<rec_nbr>0030</rec_nbr>
> 		<data>another chunk of data</data>
> 		<0040>
> 			<prefix>chunk of data</prefix>
> 			<rec_nbr>0040</rec_nbr>
> 			<data>another chunk of data</data>
> 		</0040>
> 	</0030>
> </0020>
> <0010>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0010</rec_nbr>
> 	<data>another chunk of data</data>
> </0010>
> <0020>
> 	<prefix>chunk of data</prefix>
> 	<rec_nbr>0020</rec_nbr>
> 	<data>another chunk of data</data>
> 	...
> </0020>
> 
> XLST So Far:
> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> version="1.0"
>   xmlns:pfx="http://www.tibco.com/tnt/utilitySchema";
>   xmlns:pfx2="http://www.tibco.com/bw/xslt/custom-functions";
>  
> xmlns:pfx3="http://www.tibco.com/ns/no_namespace_schema_locati
> on/SchemaName-
> 2">
> 
> <xsl:variable name="data" select="/root/rows"/>
> 
> <xsl:template match="/">
>    <xsl:for-each select="$data">
>       <xsl:if test="rec_nbr='0010'"><xsl:call-template
> name="_0010"/></xsl:if>
>       <xsl:if test="rec_nbr='0020'"><xsl:call-template name="_0020">
>                                     <xsl:with-param 
> name="position" select="position()"/>
>                                     </xsl:call-template></xsl:if>
>    </xsl:for-each>
> </xsl:template>
> 
> <xsl:template name="_0010">
>    <xsl:element name="_0010">
>       <xsl:for-each select="./*">
>          <xsl:copy-of select="."/>
>       </xsl:for-each>
>    </xsl:element>
> </xsl:template>
> 
> <xsl:template name="_0020">
>    <xsl:param name="position"/>
> 
>       <xsl:variable name="nextRecord" 
> select="$data[$position+1 = position()]"/>
> 
>       <xsl:element name="_0020">
> 
>       <xsl:copy-of select="./prefix"/>
>       <xsl:copy-of select="./rec_nbr"/>
>       <xsl:copy-of select="./data"/>
> 
>       <xsl:choose>
>          <xsl:when test="$nextRecord/rec_nbr='0030'">
>                <xsl:call-template name="_0030">
>                   <xsl:with-param name="record" select="$nextRecord"/>
>                </xsl:call-template>
>          </xsl:when>
> 
>          <xsl:otherwise>
>                <xsl:for-each select="./*">
>                   <xsl:copy-of select="."/>
>                </xsl:for-each>
>          </xsl:otherwise>
>       </xsl:choose>
> 
>       </xsl:element>
> 
> </xsl:template>
> 
> 
> <xsl:template name="_0030">
>    <xsl:param name="record"/>
> 
>    <xsl:element name="_0030">
> 
>       <xsl:copy-of select="$record/prefix"/>
>       <xsl:copy-of select="$record/rec_nbr"/>
>       <xsl:copy-of select="$record/data"/>
> 
>    </xsl:element>
> 
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> I'm not sure how to nest a <0030> in a <0020> and a <0040> in 
> a <0030> and control the opening and closing of the container 
> tags - <0020> and <0030> being the containers for <0030> and 
> <0040> respectively.
> 
> Any help in creating a XLST stylesheet is GREATLY appreciated.
> 
> smk
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 


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


Current Thread