Syntax
<xsl:key name="name" match="pattern" use="expression"/>Attributes
Attribute | Value | Description |
---|---|---|
name | name | Required. Specifies the name of the key |
match | pattern | Required. Defines the nodes to which the key will be applied |
use | expression | Required. The value of the key for each of the nodes |
To explain keys better, let me take help of following example.
Below is a XML structure depicting information about various movies being played at "My Theater" on specific dates along with their show timings.
[code]
<?xml version="1.0" encoding="UTF-8"?>[/code]
<showtimes>
<id>my theater</id>
<film>
<name>The Big Show</name>
<show>
<date>06012006</date>
<time>0500</time>
</show>
<show>
<date>06012006</date>
<time>0700</time>
</show>
<show>
<date>06012006</date>
<time>0600</time>
</show>
<show>
<date>03012006</date>
<time>0700</time>
</show>
<show>
<date>08012006</date>
<time>0500</time>
</show>
<show>
<date>08012006</date>
<time>0700</time>
</show>
</film>
<film>
<name>The Truman Show</name>
<show>
<date>09012006</date>
<time>0600</time>
</show>
<show>
<date>09012006</date>
<time>0700</time>
</show>
<show>
<date>09012006</date>
<time>0700</time>
</show>
<show>
<date>08012006</date>
<time>0700</time>
</show>
<show>
<date>03012006</date>
<time>0600</time>
</show>
<show>
<date>03012006</date>
<time>0700</time>
</show>
</film>
</showtimes>
Now, if one is to generate output as shown below, it is required that we group shows based on date. Now, to achieve this we would require xsl:key.
[output]
Movie Listings
DATE = 03012006 | Show Timings : 0600 0700 0700
DATE = 06012006 | Show Timings : 0500 0600 0700
DATE = 08012006 | Show Timings : 0500 0700 0700
DATE = 09012006 | Show Timings : 0600 0700 0700
Analyse the XSLT code to understand the functioning of keys.
[code]
<?xml version="1.0" encoding="UTF-8"?>[/code]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<--====grouping shows based on date under key with name shows======-->
<xsl:key name="shows" match="show" use="date"/>
<xsl:template match="/">
<html>
<head>
<title>Movie Listings</title>
</head>
<body>
<h1>Movie Listings</h1>
<hr/>
<--====looping for multiple films======-->
<xsl:for-each select="./showtimes/film">
<xsl:if test="position() > 1 ">
<hr/>
</xsl:if>
<xsl:apply-templates select="."/>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="id"/>
<xsl:template match="film">
<div align="center">
<b><xsl:text>Name of show : </xsl:text></b>
<b><xsl:value-of select="self::film/child::name"/></b> <br/>
</div>
<--====fetching show node [who is same as of show node of position 1
when date is union/same] ======-->
<xsl:for-each select="show[count(key('shows', date)[1] | .) = 1]">
<xsl:sort select="substring(date, 5, 4)"/>
<xsl:sort select="substring(date, 1, 2)"/>
<xsl:sort select="substring(date, 3, 2)"/>
<div>
DATE = <xsl:value-of select="date"/><xsl:text> | </xsl:text>
<xsl:text>Show Timings : </xsl:text>
<--====iterating shows from key having specific date======-->
<xsl:for-each select="key('shows', date)">
<xsl:sort select="time"/>
<xsl:value-of select="time"/>
<xsl:if test="position() < last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</div>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>