views:

59

answers:

2

Hey

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="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.

Thanks

+3  A: 
   <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>
Mark McLaren
Perfect thankyou
Chris
+2  A: 

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" />

Dimitre Novatchev