Tuesday, August 26, 2008

XSLT - Keys implementation

XSLT Keys - xsl:key is used to declare keys. If I were to define xsl:key in my lanuage, I would say, key represents a collection of nodes (as specified in use attribute) which is filterd by specific pattern as defined by "match" attribute.

Syntax

<xsl:key name="name" match="pattern" use="expression"/>
Attributes

AttributeValue 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"?>
<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>
[/code]

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


Name of show : The Big Show
DATE = 03012006 | Show Timings : 0600 0700 0700
DATE = 06012006 | Show Timings : 0500 0600 0700
DATE = 08012006 | Show Timings : 0500 0700 0700

Name of show : The Truman Show
DATE = 09012006 | Show Timings : 0600 0700 0700
[/output]

Analyse the XSLT code to understand the functioning of keys.

[code]
<?xml version="1.0" encoding="UTF-8"?>

<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>
[/code]

No comments: