RE: Re: [xsl] Repetitive variable definitions

Subject: RE: Re: [xsl] Repetitive variable definitions
From: "Scott Trenda" <Scott.Trenda@xxxxxxxx>
Date: Fri, 14 Sep 2007 16:52:03 -0500
-----Original Message-----
From: cknell@xxxxxxxxxx [mailto:cknell@xxxxxxxxxx]

Given the example XML input document, you will necessarily have to
create three different variables to hold the three values you want to
capture.
------------------------------------------------------------------------
-


I'm skeptical. Given the input and what you're trying to do with it, you
could at least reduce the variables down to a common pattern. You're not
going to completely get away from some XPath in your expression, but you
could do something like this:

<xsl:key name="cols" match="/example/table" use=".|tr|tr/td"/>

and your test would be "key('cols', .)/tr[1]/td[last()]/@col" in all
three templates. From there, if you know you're going to be using it as
an attribute in each template (for bgcolor in this case), you can do
this:


<xsl:attribute-set name="td">
  <xsl:attribute name="align">center</xsl:attribute>
  <xsl:attribute name="colspan">
    <xsl:if test="self::table">
      <xsl:value-of select="key('cols', .)/tr[1]/td[last()]/@col"/>
    </xsl:if>
  </xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="bg">
  <xsl:attribute name="bgcolor">
    <xsl:variable name="col-count" select="key('cols',
.)/tr[1]/td[last()]/@col">
    <xsl:choose>
      <xsl:when test="$col-count = 1">red</xsl:when>
      <xsl:when test="$col-count = 3">blue</xsl:when>
    </xsl:choose>
  </xsl:attribute>
</xsl:attribute-set>

<!-- in the templates -->
<tr xsl:use-attribute-sets="bg">...</tr>
<td xsl:use-attribute-sets="bg td">...</td>


I may be overgeneralizing in this particular case, but in general, when
you're creating HTML, there are several places where you're creating
attributes that are common to several other nodes. Since the content of
each <xsl:attribute> in a <xsl:attribute-set> is evaluated in the
context of the element that's using the set, you can test for any
differences in the <xsl:attribute>. Look for patterns and use global
context-aware features to merge these together if at all possible.

(Also, leverage against the XML structure itself whenever possible. Is
the value of @col ever different than the <td>'s position within its
parent node? If so, you could probably use count() or position(),
instead of specifying @col at every <td> node.)


~ Scott

Current Thread