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

RE: Grouping examples make my head spin

Subject: RE: Grouping examples make my head spin
From: "Macaulay,Malcolm (US)" <Malcolm.Macaulay2@xxxxxxxxx>
Date: Mon, 5 Aug 2002 16:52:32 -0500
xslt grouping example
Hi Charles,

Below is a sample XSLT which does (hopefully) something close to what you want. I've put comments into the XSLT to try to explain what is going on.

I used the Muenchian method to get the unique @org's - take a look at Jeni T's good website (http://www.jenitennison.com/xslt/grouping/muenchian.html) and the archives of this list for more info.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
	
	<!-- Create keyed index of contract/@org's-->
	<xsl:key name="orgsByOrg" match="/contractors/contractor/contract/@org" use="."/>
	
	<xsl:template match="/">
		<table border="1">
			<tr>
				<th>@org</th>
				<th>contractor names</th>
			</tr>
			<!-- loop through all the UNIQUE values of @org 9unique ones by Muenchian method -->
			<xsl:for-each select="contractors/contractor/contract/@org[generate-id(.)=generate-id(key('orgsByOrg',.)[1])]">
				<!--
			
				Store @org ID values for use below-->
				<xsl:variable name="orgID" select="."/>
				<tr>
					<!-- write org ID-->
					<td>
						<xsl:value-of select="."/>
					</td>
					<td>
						<!-- Build table of names of all contractors who participate on contract where @org = the current @org-->
						<table border="1">
							<xsl:for-each select="/contractors/contractor[contract/@org = $orgID]">
								<tr>
									<td>
										<xsl:value-of select="@name"/>
									</td>
								</tr>
							</xsl:for-each>
						</table>
					</td>
				</tr>
			</xsl:for-each>
		</table>
	</xsl:template>
</xsl:stylesheet>


Hope that helps.

cheers

Malcolm



-----Original Message-----
From: Charles Knell [mailto:cknell@xxxxxxxxxx]
Sent: Monday, August 05, 2002 4:10 PM
To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
Subject:  Grouping examples make my head spin


I've just started doing my first XML grouping attempt. I've been looking
over three books all day, but the solution keeps eluding my grasp. I
think my problem is that all the examples presented are based on non-hierarchical
elements, and I don't have the knowledge to abstract the principles from
them to apply it to my situation.

examples:
from XSLT Programmer's Refernce 2nd Edition, pg.623:
<cities>
	<city name="Paris" country="France" />
	<city name="Roma" country="Italia" />
	<city name="Nice" country="France" />
	...
<cities>

or from XSLT and XPath on the Edge, pg 198:
<transaction date="2001-03-01" type="DD" payee="TV License">8.91<transaction>
<transaction date="2001-03-01" type="DD" payee="British Gas">22.00<transaction>
<transaction date="2001-03-03" type="CR" payee="Client">400.00<transaction>
...

My data file is hierachical:

<contractors>
  <contractor id="x" name="A">
    <contract org="1596" contract-id="89" name="SuperDuperIII">
      <contractType>System</contractType>
      <deliverable>Application Development</deliverable>
    </contract>
    <contract org="98" contract-id="75" name="SixtySix">
      <contractType>Non-system</contractType>
      <deliverable>Neon Routers</deliverable>
    </contract>
  </contractor>
  <contractor id="16" name="W">
    <contract org="1596" contract-id="1365" name="Bosco">
      <contractType>System</contractType>
      <deliverable>Application Development</deliverable>
    </contract>
    <contract org="98" contract-id="258" name="Xanadu">
      <contractType>System</contractType>
      <deliverable>Application Development</deliverable>
    </contract>
  </contractor>
</contractors>

 I want to outpt HTML. I want each distinct value for /contractors/contractor/contract/@org
to be output exactly once, with a list (format irrelevant for the purposes
of the exercise) of /contractors/contractor/@name below that, one for
each contractor which has a contract with /contractors/contractor/contract/@org.

I think what I need to do is get a list of unique values for /contractors/contractor/contract/@org
and then loop through all instances of /contractors/contractor, checking
each value of contract/@org. If I find a new value, I want to emit an
HTML div element with that value, if the value has already been encountered,
I want to emit an HTML div element containing the value of /contractors/contractor/@name.

I have tried this template:

<xsl:template name="byPO" match="*">
  <xsl:for-each select="/contractors/contractor/contract">
    <div>Contract Org: <xsl:value-of select="@org" /></div>
    <div>Immediate preceeding sibling&apos;s contract Org: <xsl:value-of
select="preceding-sibling[1]/@org" /></div>
  </xsl:for-each>
</xsl:template>

but the output shows me that no /contractors/contractor/contract has
an immediately preceeding sibling, which I can see is not true, so there
for I am missing something in my understanding of <xsl:value-of select="preceding-sibling[1]/@org"
/>.

As usual, all help gratefully received.
Thanks.

-- 
Charles Knell
cknell@xxxxxxxxxx - email
 

 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

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.