Forum Moderators: open
I'm going to store the XPath result set into a "variable," and then iterate the "variable," thusly:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wt="http://www.example.com" exclude-result-prefixes="wt">
<xsl:output indent="yes" method="html" version="4.01" doctype-system="http://www.w3c.org/tr/html4/strict.dtd" doctype-public="-//W3c//DTD HTML 4.01//EN"/><xsl:template match="/">
<html>
<head>
<title>XML Test</title>
</head>
<body>
<h1>Category 1</h1>
<xsl:for-each select="wt:weetest/wt:elementwrapper[wt:data_cat=1]">
<xsl:call-template name="render_one"/>
</xsl:for-each>
<h1>Category 2</h1>
<xsl:for-each select="wt:weetest/wt:elementwrapper[wt:data_cat=2]">
<xsl:call-template name="render_one"/>
</xsl:for-each>
<h1>Category 3</h1>
<xsl:for-each select="wt:weetest/wt:elementwrapper[wt:data_cat=3]">
<xsl:call-template name="render_one"/>
</xsl:for-each>
<h1>More Than Ten Hours</h1>
<xsl:for-each select="wt:weetest/wt:elementwrapper[(floor(substring-before(wt:data_duration, ':'))+floor(substring-before(substring-after(wt:data_duration, ':'),':')))>10]">
<xsl:call-template name="render_one"/>
</xsl:for-each>
<h1>Less Than, or Equal to, Ten Hours</h1>
<xsl:variable name="less_than_ten_hours" select="wt:weetest/wt:elementwrapper[(floor(substring-before(wt:data_duration, ':'))+floor(substring-before(substring-after(wt:data_duration, ':'),':')))<=10]"/>
<xsl:for-each select="$less_than_ten_hours">
<xsl:call-template name="render_one"/>
</xsl:for-each>
<h1>Has Links</h1>
<xsl:for-each select="wt:weetest/wt:elementwrapper[wt:data_uri!='']">
<xsl:call-template name="render_one"/>
</xsl:for-each>
</body>
</html>
</xsl:template><xsl:template name="render_one">
<xsl:element name="div">
<xsl:attribute name="class">
<xsl:text>alt_</xsl:text>
<xsl:number value="position() mod 2" format="1"/>
</xsl:attribute>
<xsl:call-template name="display_duration">
<xsl:with-param name="duration" select="wt:data_duration"/>
</xsl:call-template>
<div class="display">
<xsl:choose>
<xsl:when test="wt:data_uri!= ''">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of disable-output-escaping="yes" select="wt:data_uri"/>
</xsl:attribute>
<xsl:value-of select="wt:data_name"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="wt:data_name"/>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:element>
</xsl:template><xsl:template name="display_duration">
<xsl:param name="duration"/>
<xsl:if test="$duration!= ''">
<xsl:variable name="hours" select="substring-before($duration, ':')"/>
<xsl:variable name="minutes" select="substring-before(substring-after($duration, ':'), ':')"/>
<xsl:element name="div">
<xsl:attribute name="class">duration_display</xsl:attribute>
<xsl:text>The duration is </xsl:text>
<xsl:if test="floor($hours)>0">
<xsl:value-of select="floor($hours)"/>
<xsl:choose>
<xsl:when test="floor($hours)>1">
<xsl:text> hours</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text> hour</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="floor($minutes)>0">
<xsl:if test="floor($hours)>0">
<xsl:text> and </xsl:text>
</xsl:if>
<xsl:value-of select="floor($minutes)"/>
<xsl:choose>
<xsl:when test="floor($minutes)>1">
<xsl:text> minutes</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text> minute</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:text> long.</xsl:text>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
In this example, we are storing the result node set into a "variable," and then proving that the entire set was stored in the "variable." It results in the following output:
<!DOCTYPE html PUBLIC "-//W3c//DTD HTML 4.01//EN" "http://www.w3c.org/tr/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>XML Test</title>
</head>
<body>
<h1>Category 1</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_0"><div class="display">Test (cat 1)</div></div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours and 1 minute long.</div>
<div class="display">Test (cat 1)</div>
</div>
<h1>Category 2</h1>
<div class="alt_1">
<div class="duration_display">The duration is 21 hours and 35 minutes long.</div>
<div class="display">Test (cat 2)</div>
</div>
<div class="alt_0"><div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 2)</a></div></div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
<h1>Category 3</h1>
<div class="alt_1"><div class="display">Test (cat 3)</div></div>
<div class="alt_0">
<div class="duration_display">The duration is 11 hours and 1 minute long.</div>
<div class="display">Test (cat 3)</div>
</div>
<h1>More Than Ten Hours</h1>
<div class="alt_1">
<div class="duration_display">The duration is 21 hours and 35 minutes long.</div>
<div class="display">Test (cat 2)</div>
</div>
<div class="alt_0">
<div class="duration_display">The duration is 11 hours and 1 minute long.</div>
<div class="display">Test (cat 3)</div>
</div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours and 1 minute long.</div>
<div class="display">Test (cat 1)</div>
</div>
<h1>Less Than, or Equal to, Ten Hours</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_0"><div class="display">Test (cat 1)</div></div>
<div class="alt_1"><div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 2)</a></div></div>
<div class="alt_0"><div class="display">Test (cat 3)</div></div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
<h1>Has Links</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_0"><div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 2)</a></div></div>
</body>
</html>
<h1>Less Than, or Equal to, Ten Hours</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_0"><div class="display">Test (cat 1)</div></div>
<div class="alt_1"><div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 2)</a></div></div>
<div class="alt_0"><div class="display">Test (cat 3)</div></div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
I mean these guys don't even have durations! How did they get past the bouncer?
It's probably because we hired a promiscuous bouncer.
We'll just work around that by hiring a second bouncer to stand inside the gate and check invitations:
<h1>Less Than, or Equal to, Ten Hours</h1>
<xsl:variable name="less_than_ten_hours" select="wt:weetest/wt:elementwrapper[(floor(substring-before(wt:data_duration, ':'))+floor(substring-before(substring-after(wt:data_duration, ':'),':')))<=10]"/>
<xsl:for-each select="$less_than_ten_hours">
<xsl:if test="wt:data_duration!= ''">
<xsl:call-template name="render_one"/>
</xsl:if>
</xsl:for-each>
Which results in:
<h1>Less Than, or Equal to, Ten Hours</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
Whew! That did it! Go Me! Go Me!
<cough> uh, sir...
<h1>Less Than, or Equal to, Ten Hours</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
This is why we need to solve the problem in the XPath expression; not in a patched-in bit of e-spackling.
We need to sober up the bouncer, not hire a second one:
<h1>Less Than, or Equal to, Ten Hours</h1>
<xsl:variable name="less_than_ten_hours"
select="wt:weetest/wt:elementwrapper[((floor(substring-before(wt:data_duration, ':'))+floor(substring-before(substring-after(wt:data_duration, ':'),':')))<=10)and(wt:data_duration!= '')]"/>
<xsl:for-each select="$less_than_ten_hours">
<xsl:call-template name="render_one"/>
</xsl:for-each>
Which results in:
<h1>Less Than, or Equal to, Ten Hours</h1>
<div class="alt_1">
<div class="duration_display">The duration is 1 hour and 5 minutes long.</div>
<div class="display"><a href="http://www.example.com/wee_test.html">Test (cat 1)</a></div>
</div>
<div class="alt_0">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
That's better.
[edited by: cmarshall at 12:57 am (utc) on April 1, 2007]
In the original test for less-than, I specified the "<" as "<". This is because XML don't want us to use the "<" character for anything but opening elements.
Awkward, but understandable. It works fine, just looks bad. However, this is at the end of a line of gobbledygook that makes me wince, so I'm not gonna cry over it.
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>
Should have been:
<div class="alt_1">
<div class="duration_display">The duration is 10 hours long.</div>
<div class="display">Test (cat 2)</div>
</div>