RE: Grouping examples make my head spin
> 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. Because you are grouping on the value of a node, you can use either of the two common techniques for finding distinct values. The simpler approach is: /contractors/contractor/contract[not(@org=preceding::contract/@org] Note the use of "preceding" rather than preceding-sibling. But this probably will be rather inefficient, so Muenchian grouping is probably better. Muenchian grouping uses the same logic whether or not the nodes to be grouped are siblings. > > 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. That sounds dangerously like procedural thinking. Always think of grouping problems in terms of two nested loops driven by the output you want to generate (not the input that you are processing). In the outer loop you want to select one representative of each group of nodes with the same @org value, and the inner loop you want to select all the nodes within that group. Michael Kay Software AG home: Michael.H.Kay@xxxxxxxxxxxx work: Michael.Kay@xxxxxxxxxxxxxx > > 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/@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/@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
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format