Re: [xsl] Grouping into a hierarchy

Subject: Re: [xsl] Grouping into a hierarchy
From: "Spencer Tickner" <spencertickner@xxxxxxxxx>
Date: Tue, 11 Dec 2007 11:23:26 -0800
Hi Tim,

For someone that's been there <xsl:for-each> statements are rarely the
way to go. The following stylesheet should solve your problem. I left
it verbose as it may help you follow some of the logic. Also you
didn't have any attributes in your example but I handled them just in
case:


<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:template match="/">
	<xsl:apply-templates/>
</xsl:template>

<xsl:template match="WorkData">
<xsl:copy>
	<xsl:copy-of select="@*"/>
		<Orders>
			<xsl:apply-templates/>
		</Orders>
</xsl:copy>
</xsl:template>

<xsl:template match="Detail"/>

<xsl:template match="Headers"><xsl:apply-templates/></xsl:template>

<xsl:template match="Header">
	<xsl:variable name="currPO" select="PO_NBR"/>
	<Order>
		<hdr>
		<xsl:apply-templates/>
		</hdr>
		<xsl:if test="/WorkData/Detail/LineItem[PO_NBR = PO_NBR]">
			<LineItems>
				<xsl:apply-templates select="/WorkData/Detail/LineItem[PO_NBR = $currPO]"/>
			</LineItems>
		</xsl:if>
	</Order>
</xsl:template>

<xsl:template match="LineItem">

</xsl:template>

<xsl:template match="Header/PO_NBR">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
			<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>

<xsl:template match="Header/PROC_IND">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
			<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>

<xsl:template match="LineItem">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>
<xsl:template match="LineItem/PO_NBR">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>
<xsl:template match="LineItem/LINE_ITEM_NBR">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>
<xsl:template match="LineItem/BG_ID">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>
<!-- expected Merged hierarchy output-->

</xsl:stylesheet>

Hope that's what you wanted.

Cheers,

Spencer

On Dec 11, 2007 9:49 AM, Tim <timlhunt@xxxxxxxxxxxxxx> wrote:
> Hi. I have a newbie question. I have been able to extract data from two
> tables, into a work area like below. The data is below with a  stlesheet
> to try to merge them, but I get all the detail.
>
> <?xml version="1.0" encoding="UTF-8"?>
> <WorkData>
>     <Headers>
>         <Header>
>             <PO_NBR>138513</PO_NBR>
>             <PROC_IND>N</PROC_IND>
>         </Header>
>         <Header>
>             <PO_NBR>138522</PO_NBR>
>             <PROC_IND>N</PROC_IND>
>         </Header>
>     </Headers>
>
>     <Detail>
>         <LineItem>
>             <PO_NBR>138513</PO_NBR>
>             <LINE_ITEM_NBR>1</LINE_ITEM_NBR>
>             <BG_ID>VL 81268</BG_ID>
>         </LineItem>
>         <LineItem>
>             <PO_NBR>138513</PO_NBR>
>             <LINE_ITEM_NBR>2</LINE_ITEM_NBR>
>             <BG_ID>VL 81200</BG_ID>
>         </LineItem>
>         <LineItem>
>             <PO_NBR>138522</PO_NBR>
>             <LINE_ITEM_NBR>1</LINE_ITEM_NBR>
>             <BG_ID>VL 81265</BG_ID>
>         </LineItem>
>     </Detail>
> </WorkData>
>
> <!-- expected Merged hierarchy output-->
> <WorkData>
>     <Orders>
>         <Order>
>             <hdr>
>                 <PO_NBR>138513</PO_NBR>
>                 <PROC_IND>N</PROC_IND>
>             </hdr>
>             <LineItems>
>                 <LineItem>
>                     <PO_NBR>138513</PO_NBR>
>                     <LINE_ITEM_NBR>1</LINE_ITEM_NBR>
>                     <BG_ID>VL 81268</BG_ID>
>                 </LineItem>
>                 <LineItem>
>                     <PO_NBR>138513</PO_NBR>
>                     <LINE_ITEM_NBR>2</LINE_ITEM_NBR>
>                     <BG_ID>VL 81200</BG_ID>
>                 </LineItem>
>             </LineItems>
>         </Order>
>         <Order>
>             <hdr>
>                 <PO_NBR>138522</PO_NBR>
>                 <PROC_IND>N</PROC_IND>
>             </hdr>
>             <LineItems>
>                 <LineItem>
>                     <PO_NBR>138522</PO_NBR>
>                     <LINE_ITEM_NBR>1</LINE_ITEM_NBR>
>                     <BG_ID>VL 81265</BG_ID>
>                 </LineItem>
>             </LineItems>
>         </Order>
>     </Orders>
> </WorkData>
>
> <!-- My XSL so far gets all the detail, rather than associating detail
> with the correct header portion: -->
> <?xml version="1.0"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>     <xsl:template match="/WorkData/Headers/Header">
>         <xsl:for-each select="/WorkData/Headers/Header">
>             <xsl:value-of select="."/>
>             <xsl:for-each select="/WorkData/Detail/LineItem/*">
>                 <xsl:value-of select="."/>
>                 <xsl:text>&#xA;</xsl:text>
>             </xsl:for-each>
>             <xsl:text>-+-&#xA;</xsl:text>
>         </xsl:for-each>
>     </xsl:template>
> </xsl:stylesheet>

Current Thread