Of Grouping, Counting, and Context
Of Grouping, Counting, and Context

Of Grouping, Counting, and Context

by John E. Simpson
July 31, 2002

John Simpson is the author of XPath and XPointer.

Q: How do I count the number of elements with a given attribute value?

My XML file looks like this:

   <Match>

      <Date>21/3/2005</Date>

      <Stadium>Wembley</Stadium>

      <Team Name="Liverpool">

         <Goal Scorer="O'Reilly"/>

         <Goal Scorer="Smith"/>

         <Goal Scorer="O'Reilly"/>

      </Team> 

      <Team Name="Real Madrid">

         <Goal Scorer="Charles"/>

         <Goal Scorer="Humble"/>

         <Goal Scorer="Humble"/>

         <Goal Scorer="Santana"/>

         <Goal Scorer="Humble"/>

      </Team>

   </Match>

I want to get output like this (for the Liverpool team):

   Player   Goals

   O'Reilly 2

   Smith    1

Any ideas?

A: Great question. The answer requires knowledge of a couple of XSLT techniques: grouping (with XSLT keys) and using the count() function.

Here's the relevant portion of an XSLT stylesheet to solve the problem; notes on the code follow, particularly on the portions which are in boldface:

   <xsl:key name="player" match="@Scorer"

use="."/>



   <xsl:template match="Team">

      <table border="1">

         <tr><th colspan="3">Team: <xsl:value-of

select="@Name"/></th></tr>

        

<tr><th>Player</th><th>Goals</th><th>Gen'd

ID</th></tr>

         <xsl:for-each

select="Goal/@Scorer[generate-id()=generate-id(key('player',

.))]">

            <tr>

               <td><xsl:value-of

select="."/></td>

               <td><xsl:value-of

select="count(../../Goal[@Scorer=current()])"/></td>



               <td><xsl:value-of

select="generate-id(.)"/></td>

            </tr>

         </xsl:for-each>

      </table>

      <br />

   </xsl:template>

Related Reading

XPath and XPointer

XPath and XPointer
Locating Content in XML Documents
By John E.Simpson

Read Online--Safari

This code fragment first sets up an XSLT key -- something like an index in DBMS terms. The name of the key is "player"; it matches on a pattern identified by the XPath expression @Scorer. The value of the key, given by the use attribute, is the string-value of that match pattern. Note that the xsl:key element is a top-level element, a child of the root xsl:stylesheet element. Thus the match pattern isn't "relative" to anything at all in the source tree -- there's nothing like a context node to which it can be relative -- until the key is actually invoked, using the key() function, by some lower-level stylesheet template or instruction. Importantly, unlike a DBMS unique index or an XML ID-type attribute, an XSLT key may point to more than one "thing" at a time. Also unlike ID-type attributes, keys aren't restricted to identifying elements only. In this case, we're going to be grouping on the basis of attributes which share the same value: the Scorer attributes in the source tree.

There's one template rule in this stylesheet fragment. For every occurrence of a Team element in the source tree, as located by the xsl:template's match attribute, the template constructs a three-column table. Two columns display the names of the scoring players on each team and the number of goals scored; I've added the third column just to demonstrate how the keying works.

The first thing of interest in the template rule is the xsl:for-each element within it. Its select attribute starts clearly enough --"for each Scorer attribute of a Goal child of the context Team element" -- but then seems to trail off into gibberish when it moves into the predicate.

[1] [2] Next

Close    To Top
  • Prev Article-XML:
  • Next Article-XML:
  • Now: Tutorial for Web and Software Design > XML > Styles > XML Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction