[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Help with staregies for outputting an incremental number in xslt


Subject: RE: [xsl] Help with staregies for outputting an incremental number in xslt
From: "Scott Trenda" <Scott.Trenda@xxxxxxxx>
Date: Thu, 29 Nov 2007 11:47:58 -0600

Adam,

If <xsl:variable> has any content, such as the <xsl:value-of/> in the
first instance below, then its result becomes what's known as a "result
tree fragment" in XSLT 1.0, and essentially becomes its own document
containing its own node-set in XSLT 2.0. However, if you leave
<xsl:variable/> empty and use the select attribute, then the variable
simply becomes a short-hand pointer to the node-set that the XPath
returns. As you could guess, the latter situation is much faster for the
processor to deal with.

Also, I was looking over the stylesheet you provided in your first
e-mail... good god, $includeLine looks convoluted. See if you can reduce
that to a single XPath expression! All you're selecting in each of those
cases is true() or false(), which is the exactly the same as the value
of the test condition in the <xsl:if> element to start with! Also, cut
down on frivolous variables when you can. If you're only using the
variable once, there's very few reasons why you shouldn't refactor it
out. Take a look at this:

Here was your initial stylesheet:
  <xsl:variable name="description"
select="../../expensys:ItemDescription"/>
  <!-- Node ommission
        Set includeLine=false for personal spend lines with CorpCardRec
personal settlement
        as we dont want to output these -->
  <xsl:variable name="includeLine">
    <xsl:choose>
      <xsl:when test="$description = 'Personal Spend'">
        <xsl:if test="$transactionType = 'CorporateCardReconciliation'">
          <xsl:if test="$corporateCardSettlementType = 'corporate'">
            <xsl:value-of select="true()"/>
          </xsl:if>
          <xsl:if test="$corporateCardSettlementType = 'personal'">
            <xsl:value-of select="false()"/>
          </xsl:if>
        </xsl:if>
        <xsl:if test="$transactionType !=
'CorporateCardReconciliation'">
          <xsl:value-of select="true()"/>
        </xsl:if>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="true()"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:if test="$includeLine='true'">
    <txn:Line>
      <txn:Number>
        <xsl:value-of select="position()"/>
      </txn:Number>
      <!-- More data from node is output here..... -->
    </txn:Line>
  </xsl:if>

The entire variable set can be factored down to this (and probably
further; you didn't specify what $transactionType or
$corporateCardSettlementType were here):
  <!-- Omit personal spend lines with CorpCardRec personal settlement
-->
  <xsl:if test="not($transactionType = 'CorporateCardReconciliation'
                and $corporateCardSettlementType = 'personal'
                and ../../expensys:ItemDescription = 'Personal Spend')">
    <txn:Line>
      <txn:Number>
        <xsl:value-of select="position()"/>
      </txn:Number>
      <!-- More data from node is output here..... -->
    </txn:Line>
  </xsl:if>

Start using better XPath expressions, and stop relying so heavily on
temporary XSLT variables. Your transformations will run faster, you'll
be able to do complicated sorting and key selections, and most
importantly, you (and other developers) will be willing to touch the
stylesheet later.



Regarding the numbering, I think you'll want to use the <xsl:number>
element in the end. It offers the most control for counting the position
of nodes in their document, regardless of their position in the context
node-set. I believe it's somewhat slower than position(), due to its
nature of counting the preceding:: and preceding-sibling:: axes, but I
don't think it'll make a noticeable difference in your stylesheet here.


Current Thread
Keywords