[xsl] Grouping examples make my head spin

Subject: [xsl] Grouping examples make my head spin
From: "Charles Knell" <cknell@xxxxxxxxxx>
Date: Mon, 05 Aug 2002 14:10:14 -0700
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


Current Thread