Subject: RE: [xsl] Grouping examples make my head spin From: "Macaulay,Malcolm (US)" <Malcolm.Macaulay2@xxxxxxxxx> Date: Mon, 5 Aug 2002 16:52:32 -0500 |
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: [xsl] 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'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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Grouping examples make my, Michael Kay | Thread | RE: [xsl] Grouping examples make my, Charles Knell |
RE: [xsl] Urgent - Assigning <xsl:v, Kimberly Hahn | Date | Re: [xsl] Finding the ancestor that, David N Bertoni/Camb |
Month |