Re: [xsl] xsl and <Div> tags - urgent please help

Subject: Re: [xsl] xsl and <Div> tags - urgent please help
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 23 May 2002 16:16:41 +0100
Hi Ana,

> <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl";>

You're using WD-xsl, which is a Microsoft-specific invention based on
an early working draft of XSLT. Your first step should be to start
using XSLT, which is a lot more powerful. Have a look at the MSXML FAQ
at http://www.netcrucible.com/ to learn about the difference and about
tools that can help you make the change.

The problem that you're facing is a grouping problem, in which you
want to group member elements together, starting each group with those
member elements whose name starts with 'T'. One way to do this in
XSLT would be to create a key that enabled you to access all the
methods for a particular class by the class name.

A key is basically a table with two columns, one holding nodes and the
other holding values. Each row in the table shows the association
between a node and a value. The name of the table is indicated by the
name attribute on xsl:key:

<xsl:key name="methods" ... />

The nodes that are present in the table are those that match the
pattern held in the match pattern of the key. Here, you want to set up
a table where the nodes are member elements whose name starts with the
letter 'M':

<xsl:key name="methods"
         match="member[starts-with(@name, 'M')]" ... />

Finally, to work out the value for each method (the class name), you
need to look at the nearest preceding sibling of the member element
whose name attribute starts with 'T'. The path for that is:

  preceding-sibling::member[starts-with(@name, 'T')][1]

That path goes in the use attribute of xsl:key:
  
<xsl:key name="methods"
         match="member[starts-with(@name, 'M')]"
         use="preceding-sibling::member[starts-with(@name, 'T')][1]" />

Once the table has been set up with the xsl:key element, you can then
get a list of all the methods for a particular class using the key()
function. The key() function has two arguments -- the first is the
name of the table ('methods') and the second is the value that you
want to look up (e.g. 'T:Car'). The key() function will look up the
value in the second column of the table, and return the nodes from the
first column of the table in the selected rows. In this case, for
example, if you did:

  key('methods', 'T:Car')

then you'd get all the member elements representing methods that
belong to the class 'T:Car'.

You want to create one div per class. So to do this, you can apply
templates to only those member elements that represent classes (whose
name starts with the letter 'T'). I'd use a mode ('class' mode, say)
as well:

  <xsl:apply-templates select="member[starts-with(@name, 'T')]"
                       mode="class" />

Then you can have a template that matches these member elements and
creates the div for you:

<xsl:template match="member" mode="class">
  <div>
    ... various stuff about the class ...
  </div>
</xsl:template>

To get the rest of the content of that div, you could apply templates
in 'method' mode to the methods, which you can retrieve using the
'methods' key and the value of the name attribute of the member
element that you're currently on:

<xsl:template match="member" mode="class">
  <div>
    ... various stuff about the class ...
    <xsl:apply-templates select="key('methods', @name)"
                         mode="method" />
  </div>
</xsl:template>

<xsl:template match="member" mode="method">
  ... various stuff about the method ...
</xsl:template>

---

In XSLT 2.0, you can do this kind of grouping with the
xsl:for-each-group element, as follows:

  <xsl:for-each-group select="member"
    group-starting-with="member[starts-with(@name, 'T')]">
    <div>
      <xsl:for-each select="current-group()">
        ... various stuff about the class and methods ...
      </xsl:for-each>
    </div>
  </xsl:for-each-group>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread