This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: grouping question


Hi Stephen,

You're getting there.  The main problem is in the way you've set up
the key:

> <xsl:key name="host-service-index" match="/domain/host" use="service"/>

This creates a hashtable of all the host elements, using the value of
their 'service' element children as the key values. The trouble is
that the 'service' elements are all empty, so they all have no value.

Now, you could try:

<xsl:key name="host-service-index"
         match="/domain/host"
         use="service/@name"/>

But that won't do you much good either.  When you use the Muenchian
method of grouping, the nodes that you *match* have to have a unique
value.  So you want to match the service elements, indexing them by
their name attribute:

<xsl:key name="host-service-index" match="service" use="@name"/>

(Note I've got rid of the tests on the ancestry of the 'service'
element - the only service elements in your document are children of
host elements, which are children of domain elements, so you don't
have to test that.)

Now, given a service name, you can find the first service element with
that name with:

  key('host-service-index', $service-name)[1]

So you can get the unique service names with:

  domain/host/service[generate-id() =
                      generate-id(key('host-service-index',
                                      @name)[1])]

(Actually this is equivalent to:

  domain/host/service[generate-id() =
                      generate-id(key('host-service-index', @name))]

 because generate-id() implicitly takes the first node in a node test.
 It's also equivalent to:

  domain/host/service[count(.|key('host-service-index', @name)[1]) = 1]

 which uses set logic to work out whether the service node you're
 looking at and the one you've retrieved from the key are the same.)

Don't worry about the fact that the key retrieves the service elements
rather than the host elements - you can always retrieve the host
elements by going up a step from the service elements, using the
parent axis:

  key('host-service-index', $service-name)/parent::host

or, equivalently:

  key('host-service-index', $service-name)/..

So, try:

<xsl:for-each
      select="domain/host/service
                 [generate-id() =
                  generate-id(key('host-service-index', @name))]">
   <xsl:sort select="@name"/>
   <p>
      <b><xsl:value-of select="@name"/></b>
      <ul>
         <xsl:for-each select="key('host-service-index', @name)/..">
            <li><xsl:value-of select="@name"/></li>
         </xsl:for-each>
      </ul>
   </p>
</xsl:for-each>

I hope that helps,

Jeni

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



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]