Hi,
Given the XML file:
<xml>
<info beforekey="a,b,c" afterkey="d,e">
<details tag="a" path="t1.gif" />
<details tag="b" path="t2.gif" />
<details tag="c" path="t3.htm" />
<details tag="d" path="t4.jpg" />
<details tag="e" path="t5.doc" />
</info>
</xml>
I need to loop through the comma separated values of the
beforekey and afterkey, grabbing the details records containing
those keys, and putting them into img tags or a/href tags depending
on the extension (img tag for gif/jpg and a for the rest).
The easiest bit is generating the img/a elements from the details
elements based on the extension. The template should match details
elements and look at the letters after the . (or use some other
algorithm of your choice) to work out what to generate:
<xsl:template match="details">
<xsl:variable name="ext"
select="substring-after(@path, '.')" />
<xsl:choose>
<xsl:when test="$ext = 'gif' or $ext = 'jpg'">
<img src="{(_at_)path}" />
</xsl:when>
<xsl:otherwise>
<a href="{(_at_)path}" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
The harder part is working through the beforekey and afterkey
attributes to work out what to do. To do this, you need to create a
recursive template that works through the string, splitting it at
commas, and apply-templates to the details element that gets selected
for the particular 'tag'. I'd use a moded recursive template as
follows:
<xsl:template match="info" mode="show">
<xsl:param name="tags" />
<xsl:choose>
<xsl:when test="contains($tags, ',')">
<xsl:variable name="tag"
select="substring-before($tags, ',')" />
<!-- show the details for the first tag -->
<xsl:apply-templates select="details[(_at_)tag = $tag]" />
<!-- recurse onto the rest of the tags -->
<xsl:apply-templates select="." mode="show">
<xsl:with-param name="tags"
select="substring-after($tags, ',')" />
</xsl:apply-templates>
</xsl:when>
<xsl:when test="$tags">
<!-- show details for the last listed tag -->
<xsl:apply-templates select="details[(_at_)tag = $tags]" />
</xsl:when>
</xsl:choose>
</xsl:template>
To get the output that you're after, you need to invoke this template
twice, once with the value of beforekey as the value of the $tags
parameter, and once with the value of afterkey as the value of the
$tags parameter:
<xsl:template match="info">
<html>
Before:
<xsl:apply-templates select="." mode="show">
<xsl:with-param name="tags" select="@beforekey" />
</xsl:apply-templates>
After:
<xsl:apply-templates select="." mode="show">
<xsl:with-param name="tags" select="@afterkey" />
</xsl:apply-templates>
</html>
</xsl:template>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list