XSL Template - reducing replication
Sorry about the extremely vague question title (any suggestions for improvements welcome)
I have an XSL document that, currently, has lots of replication that I want to reduce.
Here is the following XML snippet I am working with
<Unit Status="开发者_Go百科alive">
I am currently using the following XSL to show images based on the status of the Unit
<xsl:choose>
<xsl:when test="@Status = 'alive'">
<img src="/web/resources/graphics/accept.png" />
</xsl:when>
<xsl:when test="@Status = 'missingUnit'">
<img src="/web/resources/graphics/error.png" />
</xsl:when>
<xsl:when test="@Status = 'missingNode'">
<img src="/web/resources/graphics/exclamation.png" />
</xsl:when>
<xsl:when test="@Status = 'unexpectedUnit'">
<img src="/web/resources/graphics/exclamation_blue.png" />
</xsl:when>
<xsl:otherwise>
<!-- Should never get here -->
<img src="/web/resources/graphics/delete.png" />
</xsl:otherwise>
</xsl:choose>
How do I put this code in a template or stylesheet that will allow me to stop copying / pasting this everywhere?
<xsl:variable name="graphicspath">/web/resources/graphics</xsl:variable>
<xsl:template match="/Unit">
<xsl:call-template name="status">
<xsl:with-param name="Status" select="./@Status" />
</xsl:call-template>
</xsl:template>
<xsl:template name="status">
<xsl:param name="Status" />
<xsl:choose>
<xsl:when test="$Status = 'alive'">
<img src="{$graphicspath}/accept.png" />
</xsl:when>
<xsl:when test="$Status = 'missingUnit'">
<img src="{$graphicspath}/error.png" />
</xsl:when>
<xsl:when test="$Status = 'missingNode'">
<img src="{$graphicspath}/exclamation.png" />
</xsl:when>
<xsl:when test="$Status = 'unexpectedUnit'">
<img src="{$graphicspath}/exclamation_blue.png" />
</xsl:when>
<xsl:otherwise>
<!-- Should never get here -->
<img src="{$graphicspath}/delete.png" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
This is a classic example of a "lookup" problem. One efficient solution is to use a separate lookup xml document and search/index it using key()/<xsl:key/>
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:way"
exclude-result-prefixes="my"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vStatus" select="*/@Status"/>
<xsl:key name="kImageForStatus"
match="@image" use="../@status"/>
<my:dict>
<when status="alive" image="accept"/>
<when status="missingUnit" image="error"/>
<when status="missingNode" image="exclamation"/>
<when status="unexpectedUnit" image="exclamation_blue"/>
</my:dict>
<xsl:variable name="vLookup"
select="document('')/*/my:dict[1]"/>
<xsl:template match="/">
<xsl:variable name="vImage">
<xsl:for-each select="$vLookup">
<xsl:value-of select="key('kImageForStatus', $vStatus)"/>
</xsl:for-each>
</xsl:variable>
<img src="/web/resources/graphics/{$vImage}.png" />
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the originally provided XML document:
<Unit Status="alive"/>
the wanted result is produced:
<img src="/web/resources/graphics/accept.png" />
精彩评论